package com.itlong.cloud.property.service.impl;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.type.TypeReference;
import com.google.common.base.Joiner;
import com.itlong.cloud.POJO.DTO.property.*;
import com.itlong.cloud.POJO.DTO.sdk.CloudFaceApiDTO;
import com.itlong.cloud.POJO.DTO.smartcard.SmartCardSyncDataPullDTO;
import com.itlong.cloud.POJO.PO.*;
import com.itlong.cloud.POJO.VO.property.*;
import com.itlong.cloud.POJO.VO.sdk.SDKFaceDeviceInfoGetVO;
import com.itlong.cloud.PlatformConstants;
import com.itlong.cloud.app.dao.IAppDeviceDao;
import com.itlong.cloud.app.dao.IAppDevicePassRecordDao;
import com.itlong.cloud.commons.dao.ICloudElevatorDao;
import com.itlong.cloud.commons.dao.ICloudEntranceDao;
import com.itlong.cloud.constants.RabbitMQConstant;
import com.itlong.cloud.constants.RedisConstant;
import com.itlong.cloud.enumerate.*;
import com.itlong.cloud.property.dao.*;
import com.itlong.cloud.property.service.IPropertyAddEquipService;
import com.itlong.cloud.property.service.IPropertyDeviceAuthService;
import com.itlong.cloud.property.service.IPropertyEquipService;
import com.itlong.cloud.rabbitmq.config.MessageSender;
import com.itlong.cloud.sdk.dao.ICloudTalkSDKMediaDao;
import com.itlong.cloud.service.RedisService;
import com.itlong.cloud.smartcard.dao.ISmartCardFaceDao;
import com.itlong.cloud.thrown.DataAccessException;
import com.itlong.cloud.utils.data.handler.SqlUtil;
import com.itlong.cloud.utils.date.DateUtil;
import com.itlong.cloud.utils.file.UploadFileUtil;
import com.itlong.cloud.utils.node.JsonUtil;
import com.itlong.cloud.utils.page.Page;
import com.itlong.cloud.utils.random.LogicIdUtil;
import com.itlong.cloud.utils.words.StringHandlerUtil;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * <desc>
 *      设备管理实现类
 * </desc>
 *
 * @createDate 2017/08/29
 */
@Service
@RefreshScope
public class PropertyEquipServiceImpl implements IPropertyEquipService {

    private static final Logger LOG = LoggerFactory.getLogger(PropertyEquipServiceImpl.class);

    @Autowired
    private IPropertyEquipDao iPropertyEquipDao;
    @Autowired
    private RedisService<EquipPO> redisService;

    @Value("${" + PlatformConstants.IOT_SMART_CARD_PRODUCT_KEY + "}")
    private  String smartCardIotProductKey; //一卡通产品KEY

    @Autowired
    private MessageSender messageSender;

    //物业电梯持久层接口
    @Autowired
    private IPropertyElevatorDao iPropertyElevatorDao;

    //物业电梯归属地持久层接口
    @Autowired
    private IDeviceElevatorBridgeInfoDao iDeviceElevatorBridgeInfoDao;

    //门口机多媒体资源持久层接口
    @Autowired
    private IDeviceMediaGateDao iDeviceMediaGateDao;

    //物业门禁持久层接口
    @Autowired
    private IDeviceEntranceInfoDao iDeviceEntranceInfoDao;

    //物业电梯归属地持久层接口
    @Autowired
    private IDeviceEntranceBridgeInfoDao iDeviceEntranceBridgeInfoDao;

    //物业云对讲持久层接口
    @Autowired
    private IDeviceCloudIntercomInfoDao iDeviceCloudIntercomInfoDao;

    //物业云对讲归属地持久层接口
    @Autowired
    private IDeviceCloudIntercomBridgeInfoDao iDeviceCloudIntercomBridgeInfoDao;

    //电梯楼层映射持久层接口
    @Autowired
    private IDeviceElevatorFloorConfigDao iDeviceElevatorFloorConfigDao;

    @Autowired
    IPropertyAddEquipService iPropertyAddEquipService;

    @Autowired
    IPropertyDeviceAuthService ipropertyDeviceAuthService;

    @Autowired
    ITimeTaskAuthDeviceAddressInfoDao iTimeTaskAuthDeviceAddressInfoDao;

    @Autowired
    IPropertyDeviceAuthElevatorAuthDao iPropertyDeviceAuthElevatorAuthDao;

    @Autowired
    IPropertyDeviceAuthEntranceAuthDao iPropertyDeviceAuthEntranceAuthDao;

    @Autowired
    IPropertyDeviceAuthCloudIntercomAuthDao iPropertyDeviceAuthCloudIntercomAuthDao;

    @Autowired
    IPropertyDeviceAuthService iPropertyDeviceAuthServicel;

    @Autowired
    IDeviceElevatorFloorConfigDao floorConfigDao;

    @Autowired
    IPropertyPadDao iPropertyPadDao;

    @Autowired
    IAppDevicePassRecordDao iAppDevicePassRecordDao;

    @Autowired
    ICloudIntercomDeviceServiceDao iCloudIntercomDeviceServiceDao;

    @Autowired
    ICloudElevatorDao iCloudElevatorDao;

    @Autowired
    ISmartCardFaceDao iSmartCardFaceDao;

    @Autowired
    IDeviceAddressUserInfoServiceDao iDeviceAddressUserInfoServiceDao;

    @Autowired
    IAppDeviceDao iAppDeviceDao;

    @Autowired
    private ICloudEntranceDao iCloudEntranceDao;

    @Autowired
    ICloudTalkSDKMediaDao iCloudTalkSDKMediaDao;

    @Value("${" + PlatformConstants.FILE_FTP_HOST + "}")
    public String FILE_FTP_HOST;

    @Value("${" + PlatformConstants.FILE_FTP_PORT + "}")
    public String FILE_FTP_PORT;

    @Value("${" + PlatformConstants.FILE_FTP_USERNAME + "}")
    public String FILE_FTP_USERNAME;

    @Value("${" + PlatformConstants.FILE_FTP_PASSWORD + "}")
    public String FILE_FTP_PASSWORD;

    @Value("${" + PlatformConstants.FILE_ACCESS_URL + "}")
    public String FILE_ACCESS_URL;

    @Value("${" + PlatformConstants.NO_STANDARD_PROJECT_ID + "}")
    private  String noStandardProjectId; //一卡通产品KEY

    @Autowired
    private RedisService redisServicePassTime;

    public static final String SEPARATION = ",";

    public static final String ADDRESS_SEPARATION = "-";
/*    @Value("${" + PlatformConstants.IOT_SMART_CARD_PRODUCT_KEY + "}")
    private  String smartCardIotProductKey; //一卡通产品KEY*/

    /**
     * <desc>
     *      DEMO示例。
     * <desc/>
     *
     * @param id 主键
     * @return hello
     * @author Wenchao.L
     * @createDate 2017/08/29
     */
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public EquipPO getPersonById(Integer id) {
        EquipPO equipPOQueryResult = redisService.getObject(RedisConstant.REDIS_USER_USER_INFO_CACHE,EquipPO.class);
        if(equipPOQueryResult  == null){
            EquipPO equipPO = new EquipPO(id,null);
            equipPOQueryResult = iPropertyEquipDao.getOne(equipPO);
            redisService.set(RedisConstant.REDIS_USER_USER_INFO_CACHE,RedisConstant.REDIS_USER_USER_INFO_CACHE_TIME,equipPOQueryResult);
        }
        return equipPOQueryResult;
    }


    /**
     * <desc>
     *      DEMO示例。
     * <desc/>
     *
     * @param equipPO xxxxxx
     * @return hello
     * @author Wenchao.L
     * @createDate 2017/08/29
     */
    @Transactional(rollbackFor = Exception.class)
    public void insertPerson(EquipPO equipPO) {
        try{
            Integer result = iPropertyEquipDao.save(SqlUtil.durableData(equipPO, PlatformConstants.TABLE_SAVE));
            if (result != null){
                messageSender.send("queueDed","hello world!!!", RabbitMQConstant.RABBITMQ_USER_EXCHANGE,RabbitMQConstant.RABBITMQ_USER_SAVE_USER_INFO_ROUTING_KEY1);
            }
        }catch (Exception ex){
            //回滚当前事务
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
    }

    /**
     * <desc>
     *      分页查询设备列表
     * <desc/>
     * @param   propertyEquipGetPageDTO     物业设备数据转换对象
     * @return  分页数据
     * @author Biao.R
     * @createDate 2017/9/25
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public Page<PropertyEquipGetVO> getByPage(PropertyEquipGetPageDTO propertyEquipGetPageDTO) throws Exception {

        if (StringUtils.isBlank(propertyEquipGetPageDTO.getOrderColumn())) {
            propertyEquipGetPageDTO.setOrderColumn("t.createTime");
            propertyEquipGetPageDTO.setOrderRule("DESC");
        }
        Map<String, Object> params = SqlUtil.convertBeanToMapParams(propertyEquipGetPageDTO);
        Page<PropertyEquipGetVO> page = new Page<>();
        String deviceName = propertyEquipGetPageDTO.getDeviceName();
        if (StringUtils.isNotEmpty(deviceName)) {
            params.put("deviceNameLike", deviceName);
            params.remove("deviceName");
        }
        String deviceId = propertyEquipGetPageDTO.getDeviceId();
        if (StringUtils.isNotEmpty(deviceId)) {
            params.put("deviceIdLike", deviceId);
            params.remove("deviceId");
        }
        if(StringUtils.isNotEmpty(propertyEquipGetPageDTO.getBuildId())){
            params.put("buildId", propertyEquipGetPageDTO.getBuildId());
        }
        if(StringUtils.isNotEmpty(propertyEquipGetPageDTO.getUnitId())){
            params.put("unitId", propertyEquipGetPageDTO.getUnitId());
        }
        page.getPage().setPageSize(propertyEquipGetPageDTO.getPageSize());
        page.getPage().setCurrentPage(propertyEquipGetPageDTO.getCurrentPage());
        params.put("projectId", propertyEquipGetPageDTO.getProjectId());
        params.put("currentPage", page.getPage().getStartSlip());
        params.put("pageSize", page.getPage().getPageSize());

        List<PropertyEquipGetVO> pageList = null;
        Integer count = 0;
        if(StringUtils.isBlank(propertyEquipGetPageDTO.getDeviceType())){
            page.setRows(pageList, count);
            return page;
        }
        Integer deviceType = Integer.valueOf(propertyEquipGetPageDTO.getDeviceType());
        if (PropertyEquipTypeEnum.ENTRANCE.getType() == deviceType || PropertyEquipTypeEnum.BLUETOOTH_ENTRANCE.getType() == deviceType
                || PropertyEquipTypeEnum.CLOUD_ENTRANCE_DEVICE.getType() == deviceType || PropertyEquipTypeEnum.CLOUD_WIPPEN_DEVICE.getType() == deviceType
                || PropertyEquipTypeEnum.CLOUD_UNIBODY_FACE_DEVICE.getType() == deviceType|| PropertyEquipTypeEnum.CLOUD_UNIBODY_ENTRANCE_DEVICE.getType() == deviceType) {
            pageList = iDeviceEntranceInfoDao.getEntranceInfoPageList(params);
            List<String> list = new ArrayList<>();
            for(PropertyEquipGetVO propertyEquipGetVO : pageList){
                propertyEquipGetVO.setSupportFunction(iDeviceEntranceInfoDao.getDeviceFunctionInfo(propertyEquipGetVO.getDeviceUnique()));
                if(propertyEquipGetVO.getDeviceType().equals(PropertyEquipTypeEnum.CLOUD_WIPPEN_DEVICE.getType())){
                    propertyEquipGetVO.setIsOnLine("1".equals(redisService.get(RedisConstant.DEVICE_WIPPEN_IS_ONLINE_KEY + propertyEquipGetVO.getDeviceUnique())) ? 1 : 0);
                }else if (propertyEquipGetVO.getDeviceType().equals(PropertyEquipTypeEnum.CLOUD_UNIBODY_FACE_DEVICE.getType())) {
                    propertyEquipGetVO.setIsOnLine("1".equals(redisService.get(RedisConstant.DEVICE_UNIBODY_FACE_IS_ONLINE_KEY + propertyEquipGetVO.getDeviceUnique())) ? 1 : 0);
                }else{
                    propertyEquipGetVO.setIsOnLine("1".equals(redisService.get(RedisConstant.DEVICE_ENTRANCE_IS_ONLINE_KEY + propertyEquipGetVO.getDeviceUnique())) ? 1 : 0);
                }
            }
            count = iDeviceEntranceInfoDao.getPageCount(params);
        }
        if (PropertyEquipTypeEnum.BLUETOOTH_CALL.getType() == deviceType || PropertyEquipTypeEnum.ELEVATOR.getType() == deviceType || PropertyEquipTypeEnum.CLOUD_ELEVATOR.getType() == deviceType || PropertyEquipTypeEnum.BLUETOOTH_ELEVATOR.getType() == deviceType) {
            pageList = iPropertyElevatorDao.getPageList(params);
            for(PropertyEquipGetVO vo : pageList){
                vo.setFloorNo(iPropertyEquipDao.getMinFloorByDeviceUnique(vo.getDeviceUnique()));
                vo.setFloorNoMax(iPropertyEquipDao.getMaxFloorByDeviceUnique(vo.getDeviceUnique()));
            }
            count = iPropertyElevatorDao.getPageCount(params);
        }
        if (PropertyEquipTypeEnum.CLOUD_INTERCOM.getType() == deviceType || PropertyEquipTypeEnum.CLOUD_INTERCOM_ENTRANCE.getType() == deviceType || PropertyEquipTypeEnum.CLOUD_INTERCOM_FENCE.getType() == deviceType) {
            pageList = iDeviceCloudIntercomInfoDao.getCloudIntercomInfoPage(params);
            count = iDeviceCloudIntercomInfoDao.getPageCount(params);
        }

        if(pageList !=null && !pageList.isEmpty()){
            for (PropertyEquipGetVO equipGetVO : pageList) {
                List<PropertyEquipAddressVO> equipAddress = this.getEquipAddress(equipGetVO.getDeviceUnique(),equipGetVO.getEntranceType());
                equipGetVO.setEquipAddress(equipAddress);
            }
        }

        if(pageList !=null && !pageList.isEmpty()){
            for (PropertyEquipGetVO equipGetVO : pageList) {
                Integer type = StringHandlerUtil.getDeviceTypeByDeviceUnique(equipGetVO.getDeviceUnique());
                if(1 == type) {
                    equipGetVO.setIsOnLine("1".equals(redisService.get(RedisConstant.DEVICE_ELEVATOR_IS_ONLINE_KEY + equipGetVO.getDeviceUnique())) ? 1 : 0);
                }

//                if(2 == type) {
//                    equipGetVO.setIsOnLine("1".equals(redisService.get(RedisConstant.DEVICE_ENTRANCE_IS_ONLINE_KEY + equipGetVO.getDeviceUnique())) ? 1 : 0);
//                    if("1".equals(equipGetVO.getIsOnLine())) {
//                        continue;
//                    }
//                    equipGetVO.setIsOnLine("1".equals(redisService.get(RedisConstant.DEVICE_WIPPEN_IS_ONLINE_KEY + equipGetVO.getDeviceUnique())) ? 1 : 0);
//                    if("1".equals(equipGetVO.getIsOnLine())) {
//                        continue;
//                    }
//                    equipGetVO.setIsOnLine("1".equals(redisService.get(RedisConstant.DEVICE_UNIBODY_FACE_IS_ONLINE_KEY + equipGetVO.getDeviceUnique())) ? 1 : 0);
//                }

                if(3 == type) {
                    equipGetVO.setIsOnLine("1".equals(redisService.get(RedisConstant.DEVICE_INTERCOM_IS_ONLINE_KEY + equipGetVO.getDeviceUnique())) ||
                            "2".equals(redisService.get(RedisConstant.DEVICE_INTERCOM_IS_ONLINE_KEY + equipGetVO.getDeviceUnique()))? 1 : 0);
                }
            }
        }
        page.setRows(pageList, count);
        return page;
    }

    /**
     * <desc>
     *      根据设备唯一码查找设备
     * <desc/>
     * @param   deviceUnique   设备唯一码
     * @return  查询到的设备数据对象
     * @author Biao.R
     * @createDate 2017/9/26
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public PropertyEquipGetVO getByDeviceUnique(String deviceUnique) throws Exception {
        Integer deviceType = Integer.parseInt(StringHandlerUtil.copySubStr(deviceUnique, 8, 1));
        PropertyEquipGetVO propertyEquipGetVO = new PropertyEquipGetVO();
        DeviceElevatorInfoPO elevator = null;
        switch (PropertyEquipTypeEnum.getByEquipType(deviceType)) {
                case OUT_CALL_CONTROLLER:
                    elevator = iPropertyElevatorDao.getByDeviceUnique(deviceUnique);
                    if (elevator != null) {
                        BeanUtils.copyProperties(elevator, propertyEquipGetVO);
                        propertyEquipGetVO.setFloorNums(elevator.getFloorNum());
                        propertyEquipGetVO.setDeviceType(deviceType);
                        if(elevator.getElevatorType() != PropertyEquipTypeEnum.BLUETOOTH_CALL.getType()) {
                            //根据楼层权限标识查询实际楼层
                            Map<String, Object> floor = iPropertyElevatorDao.getFloorNumByNaturalFloorAndDeviceUnique(propertyEquipGetVO.getDeviceUnique(),
                                    propertyEquipGetVO.getFloorNo(), propertyEquipGetVO.getFloorNoMax());
                            if (floor != null) {
                                Integer floorNo = floor.get("minFloorNum") != null ? Integer.valueOf(floor.get("minFloorNum").toString()) : null;
                                Integer floorNoMax = floor.get("maxFloorNum") != null ? Integer.valueOf(floor.get("maxFloorNum").toString()) : null;
                                propertyEquipGetVO.setFloorNo(floorNo);
                                propertyEquipGetVO.setFloorNoMax(floorNoMax);
                            }
                        }
                        return propertyEquipGetVO;
                    }
                    return null;
            case ELEVATOR:
                elevator = iPropertyElevatorDao.getByDeviceUnique(deviceUnique);
                if (elevator != null) {
                    BeanUtils.copyProperties(elevator, propertyEquipGetVO);
                    propertyEquipGetVO.setDeviceType(deviceType);
                    if(elevator.getElevatorType() != PropertyEquipTypeEnum.BLUETOOTH_CALL.getType()) {
                        //根据楼层权限标识查询实际楼层
                        Map<String, Object> floor = iPropertyElevatorDao.getFloorNumByNaturalFloorAndDeviceUnique(propertyEquipGetVO.getDeviceUnique(),
                                propertyEquipGetVO.getFloorNo(), propertyEquipGetVO.getFloorNoMax());
                        if (floor != null) {
                            Integer floorNo = floor.get("minFloorNum") != null ? Integer.valueOf(floor.get("minFloorNum").toString()) : null;
                            Integer floorNoMax = floor.get("maxFloorNum") != null ? Integer.valueOf(floor.get("maxFloorNum").toString()) : null;
                            propertyEquipGetVO.setFloorNo(floorNo);
                            propertyEquipGetVO.setFloorNoMax(floorNoMax);
                        }
                    }else{
                        //查询外呼设备绑定电梯信息
                        List<BluetoothCallVO> list = iPropertyElevatorDao.getBluetoothRelation(deviceUnique);
                        propertyEquipGetVO.setCallBindInfo(list);
                    }
                    return propertyEquipGetVO;
                }
                return null;
            case ENTRANCE:
                //查询门禁信息
                DeviceEntranceInfoPO entrance = iDeviceEntranceInfoDao.getByDeviceUnique(deviceUnique);
                if (entrance != null) {
                    BeanUtils.copyProperties(entrance, propertyEquipGetVO);
                    propertyEquipGetVO.setDeviceType(deviceType);
                    //根据deviceUnique查询设备所支持功能
                    String function = iDeviceEntranceInfoDao.getDeviceFunctionInfo(deviceUnique);
                    propertyEquipGetVO.setSupportFunction(function);
                    return propertyEquipGetVO;
                }
                return null;
            case CLOUD_INTERCOM:
                //查询云对讲信息
                DeviceCloudIntercomInfoProductTypeVO cloudIntercom = iDeviceCloudIntercomInfoDao.getProductTypeByDeviceUnique(deviceUnique, null);
                if (cloudIntercom != null) {
                    BeanUtils.copyProperties(cloudIntercom, propertyEquipGetVO);
                    propertyEquipGetVO.setDeviceType(deviceType);
                    propertyEquipGetVO.setProductTypeName(cloudIntercom.getTypeCode());
                    return propertyEquipGetVO;
                }
                return null;
            default:
                return null;
        }
    }

    /**
     * <desc>
     *      根据设备唯一码删除已有设备数据
     * <desc/>
     * @param   deviceUnique   设备唯一码
     * @return
     * @author Juguang.S
     * @createDate 2019/11/4
     */
    @Override
    public void deleteByDeviceUnique(String deviceUnique) {
        Integer deviceType = Integer.parseInt(StringHandlerUtil.copySubStr(deviceUnique, 8, 1));
        if(deviceType==PropertyEquipTypeEnum.ELEVATOR.getType()){
            iPropertyElevatorDao.deleteByDeviceUnique(deviceUnique);
        }
        if(deviceType==PropertyEquipTypeEnum.ENTRANCE.getType()){
            iDeviceEntranceInfoDao.deleteByDeviceUnique(deviceUnique);
        }
    }



    /**
     * <desc>
     *      查询设备归属地址
     * <desc/>
     * @param   deviceUnique    设备唯一码
     * @return  设备归属地集合
     * @author Biao.R
     * @createDate 2017/9/27
     */
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public List<PropertyEquipAddressVO> getEquipAddress(String deviceUnique,Integer entranceType) {
        List<PropertyEquipAddressVO> returnAddressList = new ArrayList<>();
        List<EquipAddressGetVO> address = iDeviceElevatorBridgeInfoDao.getAddress(deviceUnique);
        if (address == null || address.isEmpty()) {
            return null;
        }
        for (EquipAddressGetVO equipAddressGetVO : address) {
            boolean containBuild = false;
            String buildId = equipAddressGetVO.getBuildId();
            String unitId = equipAddressGetVO.getUnitId();
            if (returnAddressList != null && !returnAddressList.isEmpty()) {
                for (PropertyEquipAddressVO returnVO : returnAddressList) {
                    if (returnVO.getBuildId().equals(buildId) && StringUtils.isNotEmpty(unitId)) {
                        //如果返回数据中包含了当前buildId,将标识符置为true
                        PropertyProjectUnitSimpleInfoVO unitVO = new PropertyProjectUnitSimpleInfoVO(unitId,
                                equipAddressGetVO.getUnitName(), equipAddressGetVO.getUnitNum());
                        returnVO.getUnits().add(unitVO);
                        containBuild = true;
                    }
                }
            }
            if (!containBuild) {
                PropertyEquipAddressVO addressVO = new PropertyEquipAddressVO(equipAddressGetVO.getBuildId(),
                        equipAddressGetVO.getBuildName(), equipAddressGetVO.getBuildNum());
                if (StringUtils.isNotEmpty(unitId)) {
                    PropertyProjectUnitSimpleInfoVO unitVO = new PropertyProjectUnitSimpleInfoVO(unitId,
                            equipAddressGetVO.getUnitName(), equipAddressGetVO.getUnitNum());
                    addressVO.getUnits().add(unitVO);
                }
                returnAddressList.add(addressVO);
            }
        }
        if (entranceType!=null && entranceType == 1) {
            for (int i=returnAddressList.size()-1;i>=0;i--) {
                if (i != 0 && returnAddressList.get(i).getBuildId().equals(returnAddressList.get(i-1).getBuildId())) {
                    returnAddressList.remove(i);
                }
            }
        }
        return returnAddressList;
    }

    /**
     * <desc>
     *      组装设备地址字符串，给前端展示
     * </desc>
     *
     * @param deviceUnique
     * @param entranceType
     * @return
     * @Author Zhu.yj
     * @createDate  2021/4/27
     */
    public String getEquipAddressStr(String deviceUnique,Integer entranceType) {
        List<EquipAddressGetVO> address = iDeviceElevatorBridgeInfoDao.getAddress(deviceUnique);

        if (entranceType != null && entranceType == 1){
            for (int i=address.size()-1;i>=0;i--) {
                if (i != 0 && address.get(i).getBuildId().equals(address.get(i-1).getBuildId())) {
                    address.remove(i);
                }
            }
        }

        StringBuilder stringBuilder =new StringBuilder();
        for (EquipAddressGetVO addressGetVO : address){
            if(stringBuilder.length() == 0){
                if (StringUtils.isNotBlank(addressGetVO.getUnitName())){
                    stringBuilder.append(addressGetVO.getBuildName()).append(ADDRESS_SEPARATION).append(addressGetVO.getUnitName());
                }else {
                    stringBuilder.append(addressGetVO.getBuildName());
                }

            }else {
                if (StringUtils.isNotBlank(addressGetVO.getUnitName())){
                    stringBuilder.append(SEPARATION).append(addressGetVO.getBuildName()).append(ADDRESS_SEPARATION).append(addressGetVO.getUnitName());
                }else {
                    stringBuilder.append(SEPARATION).append(addressGetVO.getBuildName());
                }
            }
        }
        return stringBuilder.toString();
    }

    /**
     * <desc>
     *      更新设备状态,并处理受影响用户的权限
     * <desc/>
     * @param   equipAddDTO    更新设备数据DTO
     * @author Biao.R
     * @createDate 2017/9/28
     */
    @Override
    public Integer updateStatus(PropertyCloudIntercomSaveDTO equipAddDTO) {
        try {
            List<DeviceBusinessChangeLogPO> changeLogPOS = this.updateStatusToDB(equipAddDTO);
            if (changeLogPOS!=null && !changeLogPOS.isEmpty()) {
                iPropertyAddEquipService.pushCloudIntercom(changeLogPOS);
            }
            //物业APP清除缓存
            redisService.del(RedisConstant.REDIS_PROPERTY_APP_USER_DEVICE_CACHE + equipAddDTO.getLoginUserId() + equipAddDTO.getProjectId());
        } catch (Exception e) {
            throw new DataAccessException("【物业设备服务层_PropertyEquipServiceImpl_updateStatus】更新设备状态异常", e);
        }
        return 1;
    }


    /**
     * <desc>
     *      更新设备状态时，保存设备信息到数据库
     * <desc/>
     * @param  equipAddDTO  设备数据信息DTO
     * @return 待消费的RabbitMQ生产者数据集
     * @author Biao.R
     * @createDate 2018/2/25
     */
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public List<DeviceBusinessChangeLogPO> updateStatusToDB(PropertyCloudIntercomSaveDTO equipAddDTO) throws Exception {
        String deviceUniques = equipAddDTO.getDeviceUnique();
        Integer status = equipAddDTO.getStatus();
        if (StringUtils.isEmpty(deviceUniques)) {
            return null;
        }
        List<DeviceBusinessChangeLogPO> changeLogPOS = new ArrayList<>();
        String[] deviceUniqueArr = deviceUniques.split(",");
        if (deviceUniqueArr.length > 0) {
            List<String> userIdList =  new ArrayList<>();
            String projectId = StringHandlerUtil.copySubStr(deviceUniqueArr[0], 0, 8);
            Date currentTime = new Date();
            JSONArray jsonArray = new JSONArray();
            JSONArray jsonArrayCloudElevator = new JSONArray();
            JSONArray jsonArrayCloudEntrance = new JSONArray();
            List<Map<String, Object>> batchUpdateList = new ArrayList<>();
            List<DeviceBusinessElevatorChangeLogPO> deviceBusinessChangeLogPOS = new ArrayList<>();
            List<DeviceBusinessEntranceChangeLogPO> deviceBusinessEntranceChangeLogPOS = new ArrayList<>();
            for (String deviceUnique : deviceUniqueArr) {
                List<String> list = null;
                Integer deviceType = Integer.parseInt(StringHandlerUtil.copySubStr(deviceUnique, 8, 1));
                switch (PropertyEquipTypeEnum.getByEquipType(deviceType)) {
                    case OUT_CALL_CONTROLLER:
                        //更新电梯状态
                        DeviceElevatorInfoPO out = new DeviceElevatorInfoPO(deviceUnique);
                        out.setStatus(status);
                        out.setUpdateTime(currentTime);
                        batchUpdateList.add(SqlUtil.durableData(out, PlatformConstants.TABLE_UPDATE));
                    case ELEVATOR:
                        //更新电梯状态
                        DeviceElevatorInfoPO elevator = new DeviceElevatorInfoPO(deviceUnique);
                        elevator.setStatus(status);
                        elevator.setUpdateTime(currentTime);
                        batchUpdateList.add(SqlUtil.durableData(elevator, PlatformConstants.TABLE_UPDATE));
                        DeviceElevatorInfoPO elevatorInfoPO = iPropertyElevatorDao.getByDeviceUnique(deviceUnique);
                            //如果修改的是云电梯设备的状态则推送指令
                            if (PropertyEquipTypeEnum.CLOUD_ELEVATOR.getType() == elevatorInfoPO.getElevatorType()){
                                JSONObject jsonObjectCloudElevator = new JSONObject();
                                jsonObjectCloudElevator.put("deviceUnique", deviceUnique);
                                jsonObjectCloudElevator.put("projectId", projectId);
                                jsonObjectCloudElevator.put("sn", elevatorInfoPO.getSn());
                                jsonArrayCloudElevator.add(jsonObjectCloudElevator);
                            }
                            list = getUserFaceInfo(deviceUnique,projectId);
                            if(null != list){
                                userIdList.addAll(list);
                        }
                        break;
                    case ENTRANCE:
                        DeviceEntranceInfoPO entrance = new DeviceEntranceInfoPO(deviceUnique);
                        Map<String,Object> entranceMap = iCloudEntranceDao.getBandElevatorInfo(deviceUnique);
                        if(entranceMap!=null){
                            entrance.setElevatorDeviceUnique(StringHandlerUtil.getNullOrStringForObject(entranceMap.get("elevatorDeviceUnique")));
                            entrance.setElevatorFloor(entranceMap.get("elevatorFloor") != null ? (Integer) entranceMap.get("elevatorFloor") : null);
                        }
                        entrance.setStatus(status);
                        entrance.setUpdateTime(currentTime);
                        batchUpdateList.add(SqlUtil.durableData(entrance, PlatformConstants.TABLE_UPDATE));
                        //如果修改的是云门禁设备的状态则推送指令
                        if (PropertyEquipTypeEnum.ENTRANCE.getType() == Integer.parseInt(deviceUnique.substring(8,9))){
                            JSONObject jsonObjectCloudEntance = new JSONObject();
                            jsonObjectCloudEntance.put("deviceUnique", deviceUnique);
                            //jsonObjectCloudEntance.put("projectId", projectId);
                            //jsonObjectCloudEntance.put("sn", String.format("%s%s%s",projectId,"0000",deviceUnique.substring(9,deviceUnique.length())));
                            jsonArrayCloudEntrance.add(jsonObjectCloudEntance);
                        }
                        list = getUserFaceInfo(deviceUnique,projectId);
                        if(null != list){
                            userIdList.addAll(list);
                        }
                        break;
                    case CLOUD_INTERCOM:
                        //更新云对讲状态
                        DeviceCloudIntercomInfoPO cloudIntercom = new DeviceCloudIntercomInfoPO(deviceUnique);
                        cloudIntercom.setStatus(status);
                        cloudIntercom.setUpdateTime(currentTime);
                        batchUpdateList.add(SqlUtil.durableData(cloudIntercom, PlatformConstants.TABLE_UPDATE));
                        //状态发生变化时添加硬件推送指令
                        JSONObject jsonObject = new JSONObject();
                        jsonObject.put("deviceUnique", deviceUnique);
                        jsonArray.add(jsonObject);
                        break;
                    default:
                        return null;
                }
            }
            //批量更新设备状态
            if (!batchUpdateList.isEmpty()) {
                iPropertyElevatorDao.batchUpdateEquip(batchUpdateList);
            }

            //设备地址变更，存储变更后的地址信息，等待定时任务刷新权限
            TimeTaskAuthDeviceAddressInfoPO deviceAddrPO = equipAddDTO.getTimeTaskAuthDeviceAddressInfoPO();
            if (deviceAddrPO != null) {
                iTimeTaskAuthDeviceAddressInfoDao.save(SqlUtil.durableData(deviceAddrPO, PlatformConstants.TABLE_SAVE));
            }

            //向设备推送设备云对讲指令
            if (!jsonArray.isEmpty()) {
                DeviceBusinessChangeLogPO changeLogPO = new DeviceBusinessChangeLogPO(SmartCommunityEnum.PUSH_DEVICE, jsonArray, projectId);
                changeLogPOS.add(changeLogPO);
            }

            //向设备推送设备云电梯指令
            if (!jsonArrayCloudElevator.isEmpty()) {
                DeviceBusinessElevatorChangeLogPO elevatorChangeLogPO = new DeviceBusinessElevatorChangeLogPO(projectId, CloudElevatorChangeBusinessEnum.PUSH_DEVICE_INFO,jsonArrayCloudElevator.toJSONString());
                deviceBusinessChangeLogPOS.add(elevatorChangeLogPO);
                //推送云电梯重启指令
                if(deviceBusinessChangeLogPOS != null && !deviceBusinessChangeLogPOS.isEmpty()){
                    this.pushElevator(deviceBusinessChangeLogPOS);
                }
            }
            //向云门禁推送设备指令
            if(!jsonArrayCloudEntrance.isEmpty()){
                DeviceBusinessEntranceChangeLogPO entranceChangeLogPO = new DeviceBusinessEntranceChangeLogPO(projectId,CloudEntranceChangeBusinessEnum.PUSH_DEVICE,jsonArrayCloudEntrance.toJSONString());
                deviceBusinessEntranceChangeLogPOS.add(entranceChangeLogPO);
                if(deviceBusinessEntranceChangeLogPOS!=null && !deviceBusinessEntranceChangeLogPOS.isEmpty()){
                    this.pushEntrance(deviceBusinessEntranceChangeLogPOS);
                }
            }

            //如果该项目启用了人脸识别才向c#发送增量处理
            if(userIdList!=null && iSmartCardFaceDao.isStartFaceByProjectId(projectId)>0){
                //发送C#人脸识别用户权限变更增量推送指令,先进行持久化，再由定时任务统一去处理 只有设备禁用启用时deviceUnique才不为空
                SmartCardFaceTimePullInfoPO timePullInfoPO = new SmartCardFaceTimePullInfoPO();
                timePullInfoPO.setPullId(LogicIdUtil.bussinessId());
                timePullInfoPO.setProjectId(projectId);
                timePullInfoPO.setDeviceUniqueInfo(deviceUniques);
                timePullInfoPO.setSyncStatus(1);
                timePullInfoPO.setUserIdInfo(Joiner.on(",").join(userIdList));
                timePullInfoPO.setStatus(status);
                //由于权限更新需要一分钟，故此处为了保证权限最新故90秒后再进行定时任务下发增量数据
                timePullInfoPO.setAllowSyncTime(DateUtil.addSecond(new Date(), 310));
                timePullInfoPO.setCreateTime(new Date());
                iSmartCardFaceDao.save(SqlUtil.durableData(timePullInfoPO,PlatformConstants.TABLE_SAVE));
            }
        }
        return changeLogPOS;
    }


    /**
     * <desc>
     *      根据设备唯一码注册人脸的userId集合
     * <desc/>
     *
     * @author Juguang.S
     * @createDate 2019/03/20
     */
    public List<String> getUserFaceInfo(String deviceUnique,String projectId){
        List<Map<String,Object>> builds = iSmartCardFaceDao.getAddressByDeviceUnique(deviceUnique);
        List<String> userIdList = null;
        if(builds.size() > 1 ){
            //多楼栋
            List<String> bs = new ArrayList<>();
            builds.forEach(build->{
                bs.add(build.get("buildId").toString());
            });
            userIdList = iDeviceAddressUserInfoServiceDao.getUserInfosByBuilds(bs, projectId);
        }else if(builds.size() == 1 && builds.get(0).get("unitId")!=null){
            //多单元
            String[] unit = StringHandlerUtil.splitString(builds.get(0).get("unitId").toString());
            userIdList = iDeviceAddressUserInfoServiceDao.getUserInfosByUnits(unit, projectId);
        }
        return userIdList;
    }

    /**
     * <desc>
     *      向设备推送设备云电梯指令
     * <desc/>
     *
     * @param   changeLogPOS     云电梯变更指令集合
     * @author Jiaqi.X
     * @createDate 2017/12/1
     */
    public void pushElevator(List<DeviceBusinessElevatorChangeLogPO> changeLogPOS) throws Exception {
        // 添加硬件推送指令
        if (!changeLogPOS.isEmpty()) {
            JSONObject dataJs = new JSONObject();
            dataJs.put("data", changeLogPOS);
            //云电梯
            messageSender.send(RabbitMQConstant.RABBITMQ_HANDLE_CLOUD_ELEVATOR_CHANGE_BUSINESS_QUEUE,
                    JsonUtil.toJSON(dataJs), RabbitMQConstant.RABBITMQ_CLOUD_ELEVATOR_CHANGE_BUSINESS_EXCHANGE,
                    RabbitMQConstant.RABBITMQ_CLOUD_ELEVATOR_CHANGE_BUSINESS_ROUTING_KEY);
        }
    }

    /**
     * <desc>
     *      向设备推送设备云门禁指令
     * <desc/>
     *
     * @param   changeLogPOS     云门禁变更指令集合
     * @author Juguang.S
     * @createDate 2019/02/27
     */
    public void pushEntrance(List<DeviceBusinessEntranceChangeLogPO> changeLogPOS) throws Exception {
        // 添加硬件推送指令
        if (!changeLogPOS.isEmpty()) {
            JSONObject dataJs = new JSONObject();
            dataJs.put("data", changeLogPOS);
            //云门禁
            messageSender.send(RabbitMQConstant.RABBITMQ_HANDLE_CLOUD_ENTRANCE_CHANGE_BUSINESS_QUEUE,
                    JsonUtil.toJSON(dataJs), RabbitMQConstant.RABBITMQ_CLOUD_ENTRANCE_CHANGE_BUSINESS_EXCHANGE,
                    RabbitMQConstant.RABBITMQ_CLOUD_ENTRANCE_CHANGE_BUSINESS_ROUTING_KEY);
        }
    }

    /**
     * <desc>
     *      删除设备归属地址
     * <desc/>
     * @param   propertyProjectRemoveUnitInfoDTO  删除单元信息数据传输对象
     * @author Integer  返回解绑数量
     * @createDate 2017/9/29
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public Integer deleteAddress(PropertyProjectRemoveUnitInfoDTO propertyProjectRemoveUnitInfoDTO) {

        try {
            //能够删除单元和楼栋的前提是，楼栋和单元下没有房间，没有房间，则不需要通知云对讲
//            JSONObject jsonObject = new JSONObject();
//            jsonObject.put("projectId",propertyProjectRemoveUnitInfoDTO.getProjectId());
//            DeviceBusinessChangeLogPO deviceBusinessChangeLogPO
//                    = new DeviceBusinessChangeLogPO(SmartCommunityEnum.PUSH_FULL,jsonObject);
//            messageSender.send(RabbitMQConstant.RABBITMQ_HANDLE_SMART_COMMUNITY_ORDERS_QUEUE,
//                    JSON.toJSONString(deviceBusinessChangeLogPO), RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_EXCHANGE,
//                    RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_ROUTING_KEY);

            //由于地址变更，受影响的云对讲设备应该得到参数更新通知
//            PropertyEquipAuthGetDTO propertyEquipAuthGetDTO = new PropertyEquipAuthGetDTO();
//            propertyEquipAuthGetDTO.setBuildId(propertyProjectRemoveUnitInfoDTO.getBuildId());
//            propertyEquipAuthGetDTO.setUnitId(propertyProjectRemoveUnitInfoDTO.getUnitId());
//            List<DeviceCloudIntercomSimpleVO> propertyEquipGetVOS = this.getCloudIntercomByAddr(propertyEquipAuthGetDTO);
//            List<DeviceBusinessChangeLogPO>  changeLogPOList = new ArrayList<>();
//            for (DeviceCloudIntercomSimpleVO propertyEquipGetVO:propertyEquipGetVOS){
//                DeviceBusinessChangeLogPO deviceBusinessChangeLogPO = new DeviceBusinessChangeLogPO();
//                deviceBusinessChangeLogPO.setDeviceUnique(propertyEquipGetVO.getDeviceUnique());
//                deviceBusinessChangeLogPO.setSn(propertyEquipGetVO.getSn());
//                deviceBusinessChangeLogPO.setChangeOrder(SmartCommunityEnum.PULL_DeviceAuthInfo_ALL.getRouteUrl());
//                changeLogPOList.add(deviceBusinessChangeLogPO);
//            }
//            if (!changeLogPOList.isEmpty())
//            {
//                messageSender.send(RabbitMQConstant.RABBITMQ_HANDLE_SMART_COMMUNITY_ORDERS_QUEUE,
//                        JSON.toJSONString(changeLogPOList), RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_EXCHANGE,
//                        RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_ROUTING_KEY);
//            }

            //地址四种删除情况
            //（1）仅提供了楼栋Id, 删除楼栋（会同时删除楼栋下的所有单元）
            //（2）仅提供了楼栋Id, 不删除楼栋（仅删除楼栋下的所有单元）-该业务目前不存在，暂不考虑
            //（3）仅提供了单元Id, 删除单元
            //（4）同时提供了楼栋Id和单元Id, 删除指定楼栋下的指定单元
            //rabbitmq 发送任务

            //删除多媒体资源-地址关系
            DeviceMediaRemoveGateBindAddressDTO deviceMediaRemoveGateBindAddressDTO = new DeviceMediaRemoveGateBindAddressDTO();
            deviceMediaRemoveGateBindAddressDTO.setMediaId(null);
            List<DeviceMediaBindAddressDTO> deviceMediaBindAddressDTOList = new ArrayList<>();
            DeviceMediaBindAddressDTO deviceMediaBindAddressDTO = new DeviceMediaBindAddressDTO();
            deviceMediaBindAddressDTO.setBuildId(propertyProjectRemoveUnitInfoDTO.getBuildId());
            deviceMediaBindAddressDTO.setUnitId(propertyProjectRemoveUnitInfoDTO.getUnitId());
            deviceMediaBindAddressDTOList.add(deviceMediaBindAddressDTO);
            deviceMediaRemoveGateBindAddressDTO.setRemoveAddressInfos(deviceMediaBindAddressDTOList);
            iDeviceMediaGateDao.removeMediaGateRelation(deviceMediaRemoveGateBindAddressDTO);

            //删除设备-地址关系
            Integer delElevatorCount = iDeviceElevatorBridgeInfoDao.deleteByAddress(propertyProjectRemoveUnitInfoDTO);
            Integer delEntranceCount = iDeviceEntranceBridgeInfoDao.deleteByAddress(propertyProjectRemoveUnitInfoDTO);
            Integer delCloudIntercomCount = iDeviceCloudIntercomBridgeInfoDao.deleteByAddress(propertyProjectRemoveUnitInfoDTO);
            List<String> deviceUniques = iPropertyPadDao.getDeviceUniqueByAddress(propertyProjectRemoveUnitInfoDTO);
            Integer delPadCount = iPropertyPadDao.deleteByAddress(propertyProjectRemoveUnitInfoDTO);
            // 推送平板重启指令队列
            if (deviceUniques != null && !deviceUniques.isEmpty()) {
                for (String deviceUnique : deviceUniques) {
                    //全量更新
                    PadUserAuthPushDTO dto = new PadUserAuthPushDTO();
                    Map<String,Object> data = new HashMap<>();
                    List<PadUserAuthPushDTO> dtos = new ArrayList<>();
                    dto.setDeviceUnique(deviceUnique);
                    dto.setProjectId(StringHandlerUtil.getProjectIdByDeviceUnique(deviceUnique));
                    dto.setPushType(PadChangeBusinessEnum.PUSH_FULL.getCommandType());
                    //删除设备归属地址
                    dto.setInstructionType(13);
                    dto.setSourceSystem(2);
                    dtos.add(dto);
                    data.put("data",dtos);
                    //发送平板业务指令
                    messageSender.send(RabbitMQConstant.RABBITMQ_PAD_USER_AUTH_CHANGE_PUSH_QUEUE, JsonUtil.toJSON(data),
                            RabbitMQConstant.RABBITMQ_EQUIP_EXCHANGE, RabbitMQConstant.RABBITMQ_PAD_USER_AUTH_CHANGE_PUSH_KEY);
                }
            }

            //情形（1）
            if ((propertyProjectRemoveUnitInfoDTO.getBuildId() != null) && (propertyProjectRemoveUnitInfoDTO.getUnitId() == null))
            {
                //LOG.info("RabbitMQ_项目删除楼栋地址业务生产者:"+ propertyProjectRemoveUnitInfoDTO.getBuildId());

                //删除楼栋的消费者
                JSONObject dataJs = new JSONObject();
                dataJs.put("data",propertyProjectRemoveUnitInfoDTO.getBuildId());
                messageSender.send(RabbitMQConstant.RABBITMQ_PROJECT_REMOVE_BUILD_QUEUE, JsonUtil.toJSON(dataJs), RabbitMQConstant.RABBITMQ_PROJECT_EXCHANGE,
                        RabbitMQConstant.RABBITMQ_PROJECT_REMOVE_BUILD_INFO_ROUTING_KEY);
            } else { //情形（3）（4）
                //LOG.info("RabbitMQ_项目删除单元地址业务生产者:"+JSON.toJSONString(propertyProjectRemoveUnitInfoDTO));
                //删除楼栋的消费者
                JSONObject dataJs = new JSONObject();
                dataJs.put("data",JSONObject.toJSON(propertyProjectRemoveUnitInfoDTO));
                messageSender.send(RabbitMQConstant.RABBITMQ_PROJECT_REMOVE_UNIT_QUEUE,JsonUtil.toJSON(dataJs), RabbitMQConstant.RABBITMQ_PROJECT_EXCHANGE,
                        RabbitMQConstant.RABBITMQ_PROJECT_REMOVE_UNIT_INFO_ROUTING_KEY);
            }

            return delElevatorCount + delEntranceCount + delCloudIntercomCount + delPadCount;


        } catch (Exception e) {
            //回滚当前事务
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }

        return -1;
    }


    /**
     * <desc>
     *      绑定设权限时分页获取设备
     * <desc/>
     * @param   propertyEquipAuthGetDTO  绑定设权限时分页获取设备DTO
     * @return   Page<Map<String, Object>>    返回的设备分页信息
     * @author Biao.R
     * @createDate 2017/10/9
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public Page<PropertyEquipSimpleVO> getEquipAuthByPage(PropertyEquipAuthGetDTO propertyEquipAuthGetDTO) throws Exception {
        Page<PropertyEquipSimpleVO> page = new Page<>();
        Map<String, Object> params = this.assembleSearchMap(propertyEquipAuthGetDTO, page);

        Integer deviceType = propertyEquipAuthGetDTO.getDeviceType();
        Integer pageCount;
        List<PropertyEquipSimpleVO> resultList = new ArrayList<>();
        //按设备类型查找设备信息
        switch (PropertyEquipTypeEnum.getByEquipType(deviceType)) {
            case ELEVATOR:
                pageCount = iPropertyElevatorDao.getCount(params);
                List<PropertyEquipGetVO> elevatorList = iPropertyElevatorDao.getPage(params);
                if (null != elevatorList && elevatorList.size() > 0) {
                    //电梯需要获取楼层范围
                    for (PropertyEquipGetVO propertyEquipGetVO : elevatorList) {
                        String deviceUnique = propertyEquipGetVO.getDeviceUnique();
                        PropertyEquipSimpleVO equipSimpleVO = new PropertyEquipSimpleVO(deviceUnique,
                                propertyEquipGetVO.getDeviceName(), this.getEquipAddress(deviceUnique,null));
                        //按前端要求处理楼层信息
                        //最大楼层数
                        Integer floorNoMax = propertyEquipGetVO.getFloorNoMax();
                        //楼层起始数
                        Integer floorNo = propertyEquipGetVO.getFloorNo();

                        Map<String, Object> param = new HashMap<>();
                        param.put("deviceUnique", deviceUnique);
                        if (floorNo != null && floorNoMax != null) {
                            param.put("floorNo", floorNo);
                            param.put("floorNoMax", floorNoMax);
                        }
                        List<DeviceElevatorFloorConfigPO> floorConfigPOS = iDeviceElevatorFloorConfigDao.getShowFloor(param);
                        equipSimpleVO.setFloorConfigs(floorConfigPOS);
                        equipSimpleVO.setDeviceId(propertyEquipGetVO.getDeviceId());
                        resultList.add(equipSimpleVO);
                    }
                }
                break;
            case ENTRANCE:
                pageCount = iDeviceEntranceInfoDao.getCount(params);
                List<PropertyEquipGetVO> entranceList = iDeviceEntranceInfoDao.getPage(params);
                if (null != entranceList && entranceList.size() > 0) {
                    for (PropertyEquipGetVO propertyEquipGetVO : entranceList) {
                        String deviceUnique = propertyEquipGetVO.getDeviceUnique();
                        PropertyEquipSimpleVO equipSimpleVO = new PropertyEquipSimpleVO(deviceUnique,
                                propertyEquipGetVO.getDeviceName(), this.getEquipAddress(deviceUnique,propertyEquipGetVO.getEntranceType()));
                        equipSimpleVO.setDeviceId(propertyEquipGetVO.getDeviceId());
                        resultList.add(equipSimpleVO);
                    }
                }
                break;
            case CLOUD_INTERCOM:
                pageCount = iDeviceCloudIntercomInfoDao.getCount(params);
                List<PropertyEquipGetVO> cloudIntercomList = iDeviceCloudIntercomInfoDao.getPage(params);
                if (null != cloudIntercomList && cloudIntercomList.size() > 0) {
                    for (PropertyEquipGetVO propertyEquipGetVO : cloudIntercomList) {
                        PropertyEquipSimpleVO equipSimpleVO = new PropertyEquipSimpleVO(propertyEquipGetVO.getDeviceUnique(),
                                propertyEquipGetVO.getDeviceName(), this.getEquipAddress(propertyEquipGetVO.getDeviceUnique(),null));
                        equipSimpleVO.setDeviceId(propertyEquipGetVO.getDeviceId());
                        resultList.add(equipSimpleVO);
                    }
                }
                break;
            default:
                return null;
        }
        page.setRows(resultList, pageCount);
        return page;
    }


    /**
     * <desc>
     *      获取用户设备权限列表
     * </desc>
     *
     * @param propertyEquipAuthGetDTO 绑定设权限时分页获取设备DTO
     * @return 返回的设备分页信息
     * @Author Zhu.yj
     * @createDate  2021/4/14
     */
    @Override
    public Page<PropertyEquipSimpleVO> getUserEquipAuthByPage(PropertyEquipAuthGetDTO propertyEquipAuthGetDTO) throws Exception {
        Page<PropertyEquipSimpleVO> page = new Page<>();
        Map<String, Object> params = this.assembleSearchMap(propertyEquipAuthGetDTO, page);
        Integer pageCount = 0;
        List<PropertyEquipSimpleVO> resultList = new ArrayList<>();
        params.put("deviceUniqueList", propertyEquipAuthGetDTO.getDeviceUniqueList());
        switch (PropertyEquipTypeEnum.getByEquipType(propertyEquipAuthGetDTO.getDeviceType())) {
            case ELEVATOR:

                if (StringUtils.isNotBlank(propertyEquipAuthGetDTO.getRoleName())){
                    String roleId = iPropertyEquipDao.getRoleIdByRoleName(params);
                    Set<String> deviceUniqueSet = new HashSet<>();
                    if (StringUtils.isNotBlank(roleId)){
                        List<Map<String, Object>> roleElevatorAuthMapList = iPropertyEquipDao.getElevatorAuthByGroupIds(roleId);
                        for (Map<String, Object> roleElevatorAuthMap : roleElevatorAuthMapList){
                            Map<String, String> roleElevatorFloorAuthMap = StringHandlerUtil.assembleElevatorAuth(roleElevatorAuthMap, propertyEquipAuthGetDTO.getProjectId());
                            if (roleElevatorFloorAuthMap != null && roleElevatorFloorAuthMap.keySet().size() > 0){
                                deviceUniqueSet.addAll(roleElevatorFloorAuthMap.keySet());
                            }
                        }
                    }
                    params.put("roleDeviceUniques", deviceUniqueSet);
                }

                //根据电梯名称或电梯id找出群控器的设备id (目的是根据电梯id或电梯名称查询时将一组设备查出)
//                List<String> controllerDeviceUnique =

                pageCount = iPropertyElevatorDao.getControllerPageCount(params);
                List<PropertyEquipGetVO> elevatorList = iPropertyElevatorDao.getControllerPage(params);
                if (null != elevatorList && elevatorList.size() > 0) {
                    //电梯需要获取楼层范围
                    for (PropertyEquipGetVO propertyEquipGetVO : elevatorList) {
                        //同一群控器下的电梯设备原则上楼层权限时相同的，所以仅找出其中一个处理即可
                        PropertyDeviceUserGroupVO propertyDeviceUserGroupVO = propertyEquipGetVO.getDeviceGroupList().get(0);
                        String deviceUnique = propertyDeviceUserGroupVO.getDeviceUnique();
                        PropertyEquipSimpleVO equipSimpleVO = new PropertyEquipSimpleVO();
                        //按前端要求处理楼层信息
                        //最大楼层数
                        Integer floorNoMax = propertyDeviceUserGroupVO.getFloorNoMax();
                        //楼层起始数
                        Integer floorNo = propertyDeviceUserGroupVO.getFloorNo();

                        Map<String, Object> param = new HashMap<>();
                        param.put("deviceUnique", deviceUnique);
                        if (floorNo != null && floorNoMax != null) {
                            param.put("floorNo", floorNo);
                            param.put("floorNoMax", floorNoMax);
                        }
                        List<DeviceElevatorFloorConfigPO> floorConfigPOS = iDeviceElevatorFloorConfigDao.getShowFloor(param);
                        equipSimpleVO.setFloorConfigs(floorConfigPOS);
                        equipSimpleVO.setDeviceAddress(this.getEquipAddressStr(deviceUnique, null));

                        //获取电梯的角色组
                        Map<String, String> elevatorGroups = this.getElevatorGroup(propertyEquipAuthGetDTO.getProjectId());

                        //设置电梯所属角色组
                        propertyEquipGetVO.getDeviceGroupList().forEach(item -> {
                            item.setRoleName(elevatorGroups.get(deviceUnique));
                        });
                        equipSimpleVO.setDeviceUserGroupVOList(propertyEquipGetVO.getDeviceGroupList());

                        //这里添加deviceUnique是为了沿用之前的逻辑
                        equipSimpleVO.setDeviceUnique(deviceUnique);
                        resultList.add(equipSimpleVO);
                    }
                }
                break;
            case ENTRANCE:
                pageCount = iDeviceEntranceInfoDao.getCount(params);
                List<PropertyEquipGetVO> entranceList = iDeviceEntranceInfoDao.getPage(params);
                resultList = this.assembDeviceVO(entranceList);
                break;
            case CLOUD_INTERCOM:
                //设备授权时若没传入地址，不展示云对讲设备(mark由getUserHaveAuthDevice方法传入)
                if (null == params.get("mark") && (null == params.get("buildId"))){
                    pageCount = 0;
                }else {
                    pageCount = iDeviceCloudIntercomInfoDao.getCount(params);
                    List<PropertyEquipGetVO> cloudIntercomList = iDeviceCloudIntercomInfoDao.getPage(params);
                    resultList = this.assembDeviceVO(cloudIntercomList);
                }
                break;
            default:
                return null;
        }
        page.setRows(resultList, pageCount);
        return page;
    }

    /**
     * <desc>
     *      根据设备机号或名称查找设备时否唯一
     * <desc/>
     * @param   propertyEquipGetDTO    设备唯一性查询DTO
     * @return  List<PropertyEquipGetVO>    查找出的设备集合
     * @author Biao.R
     * @createDate 2017/10/11
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public List<PropertyEquipGetVO> checkEquip(PropertyEquipGetDTO propertyEquipGetDTO) throws Exception {
        Map<String, Object> params = SqlUtil.convertBeanToMapParams(propertyEquipGetDTO);
        params.put("projectId",propertyEquipGetDTO.getProjectId());
        if(propertyEquipGetDTO.getDeviceType()!=null && propertyEquipGetDTO.getDeviceType() == 4){
            params.put("elevatorType","13");
            params.put("deviceType","1");
        }
        if(StringUtils.isNotEmpty(propertyEquipGetDTO.getDeviceUnique())){
            params.put("deviceUnique",null);
            params.put("deviceUniqueNot",propertyEquipGetDTO.getDeviceUnique());
        }
        return iPropertyElevatorDao.getEquipList(params);
    }

    /**
     * <desc>
     *      根据地址获取对应设备
     * <desc/>
     * @param   userDeviceAuthAddreddDTOS  地址信息集
     * @return   List<AppUserDeviceAuthsVO> 住户权限设备信息集
     * @author zhangs
     * @createDate 2017/10/31
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<AppUserDeviceAuthsVO> getAuthDeviceByAddress(List<UserDeviceAuthAddreddDTO> userDeviceAuthAddreddDTOS) throws Exception{
        List<AppUserDeviceAuthsVO> appUserDeviceAuthsVOS = new ArrayList<>();
        if(userDeviceAuthAddreddDTOS == null || (userDeviceAuthAddreddDTOS != null && userDeviceAuthAddreddDTOS.size() < 1)) {
            return appUserDeviceAuthsVOS;
        }
        for(UserDeviceAuthAddreddDTO userDeviceAuthAddreddDTO:userDeviceAuthAddreddDTOS) {
            appUserDeviceAuthsVOS.add(this.getEquipByAddress(userDeviceAuthAddreddDTO));
        }
        return appUserDeviceAuthsVOS;
    }

    /**
     * <desc>
     *      通过楼层映射表权限标识查询逻辑楼层名称（批量）
     * <desc/>
     * @param   deviceUnique    查询的电梯唯一码
     * @param   naturalFloors   电梯楼层映射表权限标识（多个以英文 , 分隔）
     * @return  查询出的楼层映射表对象集
     * @author Biao.R
     * @createDate 2017/11/20
     */
    @Override
    public List<DeviceElevatorFloorConfigPO> getByNaturalFloors(String deviceUnique, String naturalFloors) {
        if (StringUtils.isNotEmpty(deviceUnique)) {
            Map<String, Object> params = new HashMap<>();
            params.put("deviceUnique", deviceUnique);
            params.put("naturalFloorIn", naturalFloors);
            return iDeviceElevatorFloorConfigDao.getByNaturalFloors(params);
        }
        return null;
    }


    /**
     * <desc>
     *      通过楼层映射表权限标识查询逻辑楼层名称（批量）
     * <desc/>
     * @param   params    查询电梯对应楼层映射表的参数  {deviceUnique:naturalFloors}   如{"0000030110004":"1,2,3..."}
     * @return  查询出的楼层映射表对象集
     * @author Biao.R
     * @createDate 2017/11/20
     */
    @Override
    public List<PropertyElevatorFloorGetVO> getAllFloorByElevator(Map<String, String> params){
        return iDeviceElevatorFloorConfigDao.getAllFloorByElevator(params);
    }

    /**
     * <desc>
     *      根据设备地址获取用户拥有的设备
     * <desc/>
     * @param   userAuthDTO    设备唯一性查询DTO
     * @return  AppUserDeviceAuthsVO   查找出的设备集合
     * @author Biao.R
     * @createDate 2017/10/12
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AppUserDeviceAuthsVO getEquipByAddress(UserDeviceAuthAddreddDTO userAuthDTO) throws Exception {

        AppUserDeviceAuthsVO userAuthVO = new AppUserDeviceAuthsVO(userAuthDTO.getUserId(), userAuthDTO.getProjectId(), userAuthDTO.getAuthUserId());
        //获取用户的地址
        Map<String, Object> userAuthRoomAddrMap = userAuthDTO.getUserAuthRoomAddrMap();
        Set<String> buildIdSet = userAuthRoomAddrMap.keySet();
        if (buildIdSet.isEmpty()) {
            return null;
        }
        Map<String, String> params = new HashMap<>();
        params.put("projectId", userAuthDTO.getProjectId());
        List<AppUserGetDeviceAuthVO> deviceAuthVOList = new ArrayList<>();
        for (String buildId : buildIdSet) {
            params.put("buildId", buildId);
            Map<String, String> unitMap = (Map<String, String>) userAuthRoomAddrMap.get(buildId);
            Set<String> unitIdSet = unitMap.keySet();
            if (unitIdSet.isEmpty()) {
                continue;
            }
            for (String unitId : unitIdSet) {
                if (unitId.length() > 19) {
                    continue;
                }
                //通过地址查找该用户拥有的设备
                params.put("unitId", unitId);
                List<String> deviceUniques = iDeviceElevatorBridgeInfoDao.getEquipByAddress(params);

                //将所有设备放入PO中
                List<DeviceElevatorInfoPO> list = new ArrayList<>();

                //查询设备地址,之后用户房间地址和设备地址进行权限验证
                List<String> deviceUniqueElevator = iDeviceElevatorBridgeInfoDao.getElevatorByAddress(params);
                String[] deviceUniqueAll = new String[deviceUniqueElevator.size()];
                deviceUniqueElevator.toArray(deviceUniqueAll);
                if(deviceUniqueAll.length > 0) {
                    List<CloudElevatorLiftDoorTypeVO> listDevice = iPropertyDeviceAuthElevatorAuthDao.getDeviceLiftDoorTypeInfo(deviceUniqueAll);
                    List<CloudElevatorLiftDoorTypeVO> listUser = iPropertyDeviceAuthElevatorAuthDao.getUserLiftDoorTypeInfo(userAuthDTO.getUserId());
                    for (CloudElevatorLiftDoorTypeVO voDevice : listDevice) {
                        for (CloudElevatorLiftDoorTypeVO voUser : listUser) {

                            if(StringUtils.isNotEmpty(noStandardProjectId) && noStandardProjectId.contains(StringHandlerUtil.getProjectIdByDeviceUnique(voDevice.getDeviceUnique()))){
                                if (voDevice.getUnitId().equals(voUser.getUnitId())) {
                                    DeviceElevatorInfoPO po = new DeviceElevatorInfoPO();
                                    po.setDeviceUnique(voDevice.getDeviceUnique());
                                    po.setLiftDoorType(Integer.parseInt(voDevice.getLiftDoorType()));
                                    po.setUnitId(voDevice.getUnitId());
                                    list.add(po);
                                    continue;
                                }
                            }else{
                                if (voDevice.getUnitId().equals(voUser.getUnitId()) && voUser.getLiftDoorType().contains(voDevice.getLiftDoorType())) {
                                    DeviceElevatorInfoPO po = new DeviceElevatorInfoPO();
                                    po.setDeviceUnique(voDevice.getDeviceUnique());
                                    po.setLiftDoorType(Integer.parseInt(voDevice.getLiftDoorType()));
                                    po.setUnitId(voDevice.getUnitId());
                                    list.add(po);
                                    continue;
                                }
                            }
                        }
                    }
                }
                for (String deviceUnique : deviceUniques) {
                    DeviceElevatorInfoPO po = new DeviceElevatorInfoPO();
                    po.setDeviceUnique(deviceUnique);
                    list.add(po);
                }
                if (list.size() == 0) {
                    continue;
                }

                for (DeviceElevatorInfoPO po : list) {
                    AppUserGetDeviceAuthVO appUserGetDeviceAuthVO = new AppUserGetDeviceAuthVO();
                    appUserGetDeviceAuthVO.setDeviceUnique(po.getDeviceUnique());
                    String deviceType = StringHandlerUtil.copySubStr(po.getDeviceUnique(), 8, 1);
                    appUserGetDeviceAuthVO.setDeviceType(deviceType);
                    if (PropertyEquipTypeEnum.ELEVATOR.getType().toString().equals(deviceType)) {
                        //如果设备类型是电梯时，需精确到该用户所在的楼层权限:通过房号所在的楼层去查找logicalFloor对应的naturalFloor
                        String roomNums = unitMap.get(unitId);
                        if (StringUtils.isNotBlank(roomNums)) {
                            String[] roomNumArr = roomNums.split(",");
                            Set<String> floorSet = new HashSet<>();
                            for (String roomNum : roomNumArr) {
                                //进行正背门判断
                                String liftDoorType = unitMap.get(unitId+roomNum);
                                //LOG.info("deviceUnique"+po.getDeviceUnique());
                                //LOG.info("po.getUnitId()"+po.getUnitId());
                                //LOG.info("unitId"+unitId);
                                //LOG.info("liftDoorType"+liftDoorType);
                                //LOG.info("po.getLiftDoorType()"+po.getLiftDoorType());
                                //此处针对合景泰富非标项目编号(为一个机号的贯通门 通过房间正背门来区分用户在电梯的权限正背属性)单独处理
                                if(StringUtils.isNotEmpty(noStandardProjectId) && noStandardProjectId.contains(StringHandlerUtil.getProjectIdByDeviceUnique(po.getDeviceUnique()))){
                                    String naturalFloor = this.getNaturalFlrByRoomFloor(po.getDeviceUnique(),
                                            roomNum.substring(0, roomNum.length() - 2).replaceAll("^(0+)", ""));
                                    if (StringUtils.isNotEmpty(naturalFloor)) {
                                        floorSet.add(naturalFloor);
                                    }
                                    //LOG.info("【权限变更正背门】非标项目处理");
                                }else{
                                    if (po.getUnitId().equals(unitId) && po.getLiftDoorType().toString().equals(liftDoorType)) {
                                        String naturalFloor = this.getNaturalFlrByRoomFloor(po.getDeviceUnique(),
                                                roomNum.substring(0, roomNum.length() - 2).replaceAll("^(0+)", ""));
                                        if (StringUtils.isNotEmpty(naturalFloor)) {
                                            floorSet.add(naturalFloor);
                                        }
                                    }
                                    //LOG.info("【权限变更正背门】正常项目处理");
                                }
                            }
                            appUserGetDeviceAuthVO.setNaturalFloor(StringUtils.join(floorSet, ","));
                        }
                    }
                    deviceAuthVOList.add(appUserGetDeviceAuthVO);
                }
            }
        }
        userAuthVO.setAppUserGetDeviceAuthVOS(deviceAuthVOList);
        return userAuthVO;
    }

    /**
     * <desc>
     *      根据地址查询云对讲设备
     * <desc/>
     * @param   propertyEquipAuthGetDTO    设备类型
     * @return   List<PropertyEquipGetVO> 查询结果集
     * @author Biao.R
     * @createDate 2017/11/1
     */
    @Override
    public List<DeviceCloudIntercomSimpleVO> getCloudIntercomByAddr(PropertyEquipAuthGetDTO propertyEquipAuthGetDTO) {
        try {
            Map<String,Object> params = new HashMap<>();
            params.put("projectId",propertyEquipAuthGetDTO.getProjectId());
            if ((propertyEquipAuthGetDTO.getDeviceType()) != null) {
                params.put("smartType", propertyEquipAuthGetDTO.getDeviceType());
            }
            if(StringUtils.isNotEmpty(propertyEquipAuthGetDTO.getBuildId())){
                params.put("buildId",propertyEquipAuthGetDTO.getBuildId());
            }
            if(StringUtils.isNotEmpty(propertyEquipAuthGetDTO.getUnitId())){
                params.put("unitId",propertyEquipAuthGetDTO.getUnitId());
            }
            if(StringUtils.isNotEmpty(propertyEquipAuthGetDTO.getProjectId())){
                params.put("projectId",propertyEquipAuthGetDTO.getProjectId());
            }
            return iDeviceCloudIntercomInfoDao.getCloudIntercomByAddr(params);
        } catch (Exception e) {
            throw new DataAccessException("Service层:getCloudIntercomByAddr异常",e);
        }
    }


    /**
     * <desc>
     *      通过房间楼层获取电梯NaturalFloor
     * <desc/>
     * @param  deviceUnique 电梯的设备唯一码
     * @param  floorNum 房间所在的楼层
     * @return 查询到的NaturalFloor
     * @author Biao.R
     * @createDate 2017/12/18
     */
    public String getNaturalFlrByRoomFloor(String deviceUnique, String floorNum) {
        String naturalFloor = "";
        if (StringUtils.isEmpty(deviceUnique) || StringUtils.isEmpty(floorNum)) {
            return "";
        }
        //由于logicalFloor后面可能跟英文： F  也可能跟中文：层/楼，需要区别对待
        //整数正则表达式：含负整数
        String intRegex = "^-?[1-9]\\d*$";
        Map<String, Object> param = new HashMap<>();
        param.put("deviceUnique", deviceUnique);
        //根据floorNum查询
        param.put("floorNum", Integer.valueOf(floorNum).toString());
        List<String> naturalFloors = iDeviceElevatorFloorConfigDao.getNaturalFloor(param);
        if (naturalFloors != null && !naturalFloors.isEmpty() && naturalFloors.get(0).matches(intRegex)) {
            naturalFloor = naturalFloors.get(0);
        }

        if (StringUtils.isEmpty(naturalFloor)) {
            //LOG.error("===没有找到该电梯在该房间的楼层映射信息：deviceUnique:" + deviceUnique + " ==floorNum:" + floorNum);
        }
        return naturalFloor;
    }

    /**
     * <desc>
     *      根据projectId查询项目云对讲设备数量
     * <desc/>
     * @param  projectId    查询的小区ID
     * @return 云对讲设备数量
     * @author Biao.R
     * @createDate 2018/1/12
     */
    @Override
    public Integer countCloudEquipByProjectId(String projectId) {
        return iDeviceCloudIntercomInfoDao.countCloudEquipByProjectId(projectId);
    }

    /**
     * <desc>
     *      根据projectId查询项目云对讲所有设备
     * </desc>
     *
     * @param propertyIntercomGetByProjectIdDTO 查询设备传输对象
     * @return 项目所有云对讲设备
     * @author wangzhi
     * @createDate 2018/3/26
     */
    @Override
    public Page<PropertyAllEquipGetVO> getAllEquipsByProjectId(PropertyIntercomGetByProjectIdDTO propertyIntercomGetByProjectIdDTO) throws Exception {
        // 将DTO转换为Map params
        Map<String,Object> params = SqlUtil.convertBeanToMapParams(propertyIntercomGetByProjectIdDTO);

        Page<PropertyAllEquipGetVO> page = new Page<>();
        page.getPage().setPageSize(propertyIntercomGetByProjectIdDTO.getPageSize());
        page.getPage().setCurrentPage(propertyIntercomGetByProjectIdDTO.getCurrentPage());
        params.put("currentPage",page.getPage().getStartSlip());
        params.put("pageSize",page.getPage().getPageSize());

        List<PropertyAllEquipGetVO> propertyAllEquipGetVOs = iDeviceCloudIntercomInfoDao.getAllEquipsByProjectId(params);

        //加一个临时id，方便前端做判断
        /*if(null != propertyAllEquipGetVOs && !propertyAllEquipGetVOs.isEmpty()){
            int i = 0;
            for (PropertyAllEquipGetVO propertyAllEquipGetVO:propertyAllEquipGetVOs){
                propertyAllEquipGetVO.setCacheId(i++);
            }
        }*/

        //填充返回数据集
        page.setRows(propertyAllEquipGetVOs,iDeviceCloudIntercomInfoDao.getAllEquipsByProjectIdCount(params));

        return page;
//        return iDeviceCloudIntercomInfoDao.getAllEquipsByProjectId(params);
    }

    /**
     * <desc>
     *      查找云电梯产品型号信息
     * </desc>
     *
     * @param typeId 云电梯类型
     * @return
     * @author Juguang.S
     * @createDate 2018/4/16
     */
    @Override
    public ProductTypePO getTypeId(Integer typeId) {
        return iPropertyElevatorDao.getTypeId(typeId);
    }

    /**
     * <desc>
     *      根据设备唯一码获取有设备权限的一卡通用户
     * </desc>
     *
     * @param deviceUnique 设备唯一码
     * @return
     * @author JuGuang.S
     * @createDate 2018-04-17
     */
    @Override
    public List<EquipAuthUserGetVO> getSmartCardUser(String deviceUnique){
        Integer deviceId = Integer.parseInt(StringHandlerUtil.getDeviceIdByDeviceUnique(deviceUnique));
        Integer deviceType = StringHandlerUtil.getDeviceTypeByDeviceUnique(deviceUnique);
        String projectId = StringHandlerUtil.getProjectIdByDeviceUnique(deviceUnique);
        Map<String,Object> param = new HashMap<>();
        param.put("deviceId",deviceId);
        param.put("projectId",projectId);
        List<EquipAuthUserGetVO> lists = null;
        switch (PropertyEquipTypeEnum.getByEquipType(deviceType)){
            case ELEVATOR:
                lists = iPropertyDeviceAuthElevatorAuthDao.getSmartCardUser(param);
                break;
            case ENTRANCE:
                lists = iPropertyDeviceAuthEntranceAuthDao.getSmartCardUser(param);
                break;
            case CLOUD_INTERCOM:
                lists = iPropertyDeviceAuthCloudIntercomAuthDao.getSmartCardUser(param);
                break;
            default:
                return lists;
        }
        return lists;

    }


    /**
     * <desc>
     *      查询设备归属地址
     * <desc/>
     * @param   deviceUnique    设备唯一码
     * @return  设备归属地集合
     * @author Biao.R
     * @createDate 2017/9/27
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public List<PropertyEquipAddressVO> getEquipAddressBynotAdress(String deviceUnique) {
        List<PropertyEquipAddressVO> returnAddressList = new ArrayList<>();
        List<EquipAddressGetVO> address = iDeviceElevatorBridgeInfoDao.getAddress(deviceUnique);
        if (address == null || address.isEmpty()) {
            return null;
        }
        for (EquipAddressGetVO equipAddressGetVO : address) {
            boolean containBuild = false;
            String buildId = equipAddressGetVO.getBuildId();
            String unitId = equipAddressGetVO.getUnitId();
            if (returnAddressList != null && !returnAddressList.isEmpty()) {
                for (PropertyEquipAddressVO returnVO : returnAddressList) {
                    if (returnVO.getBuildId().equals(buildId) && StringUtils.isNotEmpty(unitId)) {
                        //如果返回数据中包含了当前buildId,将标识符置为true
                        PropertyProjectUnitSimpleInfoVO unitVO = new PropertyProjectUnitSimpleInfoVO(unitId,
                                equipAddressGetVO.getUnitName(), equipAddressGetVO.getUnitNum());
                        returnVO.getUnits().add(unitVO);
                        containBuild = true;
                    }
                }
            }
            if (!containBuild) {
                if(StringUtils.isNotEmpty(equipAddressGetVO.getBuildId()) && StringUtils.isNotEmpty(equipAddressGetVO.getBuildName()) && StringUtils.isNotEmpty(equipAddressGetVO.getBuildNum())){
                    PropertyEquipAddressVO addressVO = new PropertyEquipAddressVO(equipAddressGetVO.getBuildId(),
                            equipAddressGetVO.getBuildName(), equipAddressGetVO.getBuildNum());
                    if (StringUtils.isNotEmpty(unitId)) {
                        PropertyProjectUnitSimpleInfoVO unitVO = new PropertyProjectUnitSimpleInfoVO(unitId,
                                equipAddressGetVO.getUnitName(), equipAddressGetVO.getUnitNum());
                        addressVO.getUnits().add(unitVO);
                    }
                    returnAddressList.add(addressVO);
                }
            }
        }
        if(returnAddressList.size()==0){
            return null;
        }
        if (deviceUnique.substring(8,9).equals("2")) {
            DeviceEntranceInfoPO po = iDeviceEntranceInfoDao.getByDeviceUnique(deviceUnique);
            if (po != null && po.getEntranceType() != null && po.getEntranceType() == 1) {
                for (int i=returnAddressList.size()-1;i>=0;i--) {
                    if (i != 0 && returnAddressList.get(i).getBuildId().equals(returnAddressList.get(i-1).getBuildId())) {
                        returnAddressList.remove(i);
                    }
                }
            }
        }
        return returnAddressList;
    }

    /**
     * <desc>
     *      分页查询项目下或多媒体资源所绑定的所有支持平板人脸识别的设备
     * </desc>
     *
     * @param propertyPadFaceRecognitionGetForMediaDTO 使用projectId或mediaId查询该项目下所有支持人脸识别的云电梯或门禁设备数据传输对象
     * @return 分页查询结果
     * @author wangzhi
     * @createDate 2018/05/11
     */
    @Override
    public Page<PropertyPadFaceEquipVO> getPadFaceEquipByPage(PropertyPadFaceRecognitionGetForMediaDTO propertyPadFaceRecognitionGetForMediaDTO) throws Exception {

        Page<PropertyPadFaceEquipVO> page = new Page<>();

        if (propertyPadFaceRecognitionGetForMediaDTO.getChildrenType() == PropertyEquipTypeEnum.ENTRANCE.getType()){
            // 类别为门禁，查询支持平板人脸识别的门禁设备
            // 将DTO转换为Map params
            Map<String,Object> params = SqlUtil.convertBeanToMapParams(propertyPadFaceRecognitionGetForMediaDTO);
            page.getPage().setPageSize(propertyPadFaceRecognitionGetForMediaDTO.getPageSize());
            page.getPage().setCurrentPage(propertyPadFaceRecognitionGetForMediaDTO.getCurrentPage());
            params.put("currentPage",page.getPage().getStartSlip());
            params.put("pageSize",page.getPage().getPageSize());

            List<PropertyPadFaceEquipVO> propertyPadFaceEquipVOS = iDeviceEntranceInfoDao.getFaceEntrance(params);

            //填充返回数据集
            page.setRows(propertyPadFaceEquipVOS,iDeviceEntranceInfoDao.getFaceEntranceCount(params));

        }
        if (propertyPadFaceRecognitionGetForMediaDTO.getChildrenType() == PropertyEquipTypeEnum.CLOUD_ELEVATOR.getType()){
            // 类别为云电梯，查询支持平板人脸识别的云电梯设备
            // 将DTO转换为Map params
            Map<String,Object> params = SqlUtil.convertBeanToMapParams(propertyPadFaceRecognitionGetForMediaDTO);
            page.getPage().setPageSize(propertyPadFaceRecognitionGetForMediaDTO.getPageSize());
            page.getPage().setCurrentPage(propertyPadFaceRecognitionGetForMediaDTO.getCurrentPage());
            params.put("currentPage",page.getPage().getStartSlip());
            params.put("pageSize",page.getPage().getPageSize());

            List<PropertyPadFaceEquipVO> propertyPadFaceEquipVOS = iPropertyElevatorDao.getFaceCloudElevator(params);

            //填充返回数据集
            page.setRows(propertyPadFaceEquipVOS,iPropertyElevatorDao.getFaceCloudElevatorCount(params));
        }
        if (propertyPadFaceRecognitionGetForMediaDTO.getChildrenType() == PropertyEquipTypeEnum.CLOUD_UNIBODY_FACE_DEVICE.getType()){
            // 查询一体式人脸识别门禁
            // 将DTO转换为Map params
            Map<String,Object> params = SqlUtil.convertBeanToMapParams(propertyPadFaceRecognitionGetForMediaDTO);
            page.getPage().setPageSize(propertyPadFaceRecognitionGetForMediaDTO.getPageSize());
            page.getPage().setCurrentPage(propertyPadFaceRecognitionGetForMediaDTO.getCurrentPage());
            params.put("currentPage",page.getPage().getStartSlip());
            params.put("pageSize",page.getPage().getPageSize());

            List<PropertyPadFaceEquipVO> propertyPadFaceEquipVOS = iDeviceEntranceInfoDao.getUnibodyFaceEntrance(params);

            //填充返回数据集
            page.setRows(propertyPadFaceEquipVOS,iDeviceEntranceInfoDao.getUnibodyFaceEntranceCount(params));
        }
        return page;
    }

    /**
     * <desc>
     *      根据电梯设备的楼层范围变更重新设置物业临时授权的用户楼层权限
     * </desc>
     *
     * @param dto
     * @author Jiaqi.X
     * @createDate 2018/07/12
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public void changeUserElevatorFloorAuthByDeviceFloorChange(ElevatorFloorChangeDTO dto) throws Exception {
        //更新权限的用户id
        Set<String> userIds = new HashSet<>();
        //获取机号
        int deviceId = Integer.valueOf(dto.getDeviceUnique().substring(dto.getDeviceUnique().length() - 4, dto.getDeviceUnique().length()));
        //查询所有拥有该电梯的用户临时权限
        List<DeviceElevatorAuthPO> list = iPropertyElevatorDao.
                getUserAuthsByDeviceId(deviceId , dto.getProjectId());
        List<Map<String,Object>> temps = new ArrayList<>();
        for(DeviceElevatorAuthPO po : list){
            userIds.add(po.getUserId());
            Map<String,Object> tempVO = this.getOldUserTempAuth(po.getUserId(),dto.getProjectId());
            temps.add(tempVO);
            String deviceAuth = po.getDeviceAuth();
            //找到当前用户拥有该设备机号位置在二进制数据中为1的下标
            int num = -1;
            int id = -1;
            for(int i = 0 ;i < 384 ; i++){
                id++;
                if(deviceAuth.substring(i,i+1).equals("1")){
                    num++;
                    if((i+1)==deviceId){
                        break;
                    }
                }
            }
            List<String> floorAuths = new ArrayList<>(Arrays.asList(StringHandlerUtil.splitString(po.getFloorAuth())));
            //获取更改的该机号的楼层权限
            List<String> floorAuthList = new ArrayList<>();
            String[] floors = StringHandlerUtil.splitString(StringHandlerUtil.convertFloor(StringHandlerUtil.hexToBinary(floorAuths.get(num)), "1"));
            for(String floor : floors){
                String f = StringHandlerUtil.getNullOrStringForObject(dto.getNewFloors().get(
                        StringHandlerUtil.getNullOrStringForObject(dto.getOldFloors().get(floor))));
                if(StringUtils.isNotBlank(f)){
                    floorAuthList.add(f);
                }
            }
            String floorAuth = StringUtils.join(floorAuthList.toArray(new String[floorAuthList.size()]), ",");
            floorAuth = StringHandlerUtil.getCloudElevatorInFloorBinary(floorAuth,1);
            //判断变更楼层后用户是否还有楼层权限 如没有需清除该用户的电梯临时授权
            if(floorAuth.indexOf("1") < 0){
                StringBuilder da = new StringBuilder(deviceAuth);
                da=da.replace(id,id+1,"0");
                deviceAuth = da.toString();
                floorAuths.remove(num);
            }else {
                //更新完用户的楼层权限后替换掉原电梯权限及楼层权限
                floorAuths.set(num,StringHandlerUtil.binaryToHex(floorAuth.toString()).toUpperCase());
            }
            po.setDeviceAuth(deviceAuth);
            po.setFloorAuth(StringUtils.join(floorAuths,","));
            po.setProjectId(dto.getProjectId());
            //更新用户楼层权限
            iPropertyDeviceAuthElevatorAuthDao.update(po);
        }
        for(Map<String,Object> tempVo : temps){
            String userId = tempVo.get("userId").toString();
            String projectId = tempVo.get("projectId").toString();
            //发送临时权限数据
            List<DeviceBusinessChangeLogPO> changes = new ArrayList<>();
            List<DeviceBusinessElevatorChangeLogPO> elevatorChanges = new ArrayList<>();
            List<DeviceBusinessEntranceChangeLogPO> entranceChanges = new ArrayList<>();
            Map<String,Object> auth = new HashMap<>();
            auth.put("userId",userId);
            auth.put("projectId",projectId);
            auth.put("type",1);
            DeviceBusinessChangeLogPO po=new DeviceBusinessChangeLogPO(SmartCommunityEnum.PUSH_TEMP_AUTH,JsonUtil.toJSON(auth),projectId);
            changes.add(po);
            DeviceBusinessElevatorChangeLogPO elevatorPo = new DeviceBusinessElevatorChangeLogPO(projectId,CloudElevatorChangeBusinessEnum.PUSH_TEMP_AUTH,JsonUtil.toJSON(auth));
            elevatorChanges.add(elevatorPo);
            DeviceBusinessEntranceChangeLogPO entrancePO = new DeviceBusinessEntranceChangeLogPO(projectId,CloudEntranceChangeBusinessEnum.PUSH_TEMP_AUTH, JsonUtil.toJSON(auth));
            entranceChanges.add(entrancePO);
            JSONObject pushJs = new JSONObject();
            pushJs.put("data",changes);
            //发送云对讲业务指令
            messageSender.send(RabbitMQConstant.RABBITMQ_HANDLE_SMART_COMMUNITY_ORDERS_QUEUE,JsonUtil.toJSON(pushJs), RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_EXCHANGE, RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_ROUTING_KEY);
            pushJs.put("data",elevatorChanges);
            //推送云电梯业务指令
            messageSender.send(
                    RabbitMQConstant.RABBITMQ_HANDLE_CLOUD_ELEVATOR_CHANGE_BUSINESS_QUEUE,
                    JsonUtil.toJSON(pushJs),
                    RabbitMQConstant.RABBITMQ_CLOUD_ELEVATOR_CHANGE_BUSINESS_EXCHANGE,
                    RabbitMQConstant.RABBITMQ_CLOUD_ELEVATOR_CHANGE_BUSINESS_ROUTING_KEY);
            //发送云门禁业务指令
            pushJs.put("data",entranceChanges);
            messageSender.send(
                    RabbitMQConstant.RABBITMQ_HANDLE_CLOUD_ENTRANCE_CHANGE_BUSINESS_QUEUE,
                    JSON.toJSONString(pushJs),
                    RabbitMQConstant.RABBITMQ_CLOUD_ENTRANCE_CHANGE_BUSINESS_EXCHANGE,
                    RabbitMQConstant.RABBITMQ_CLOUD_ENTRANCE_CHANGE_BUSINESS_ROUTING_KEY
            );
        }
        this.sendDeviceSmartCardChange(userIds.toArray(new String[userIds.size()]),dto.getProjectId());
    }


    /**
     * <desc>
     *      获取旧用户临时权限信息
     * </desc>
     *
     * @param userId
     * @param projectId
     * @return
     * @author Jiaqi.X
     * @createDate 2019/09/25
     */
    public Map<String,Object> getOldUserTempAuth(String userId,String projectId){
        Map<String,Object> result = new HashMap<>();
        //获取用户门禁临时权限
        String doorAuth = iPropertyEquipDao.getDoorTempAuth(userId, projectId);
        if(StringUtils.isNotBlank(doorAuth)) {
            doorAuth = StringHandlerUtil.convertAuth(doorAuth, "8");
            result.put("doorAuth",doorAuth);
        }
        //获取用户电梯临时权限
        String elevatorAuth = iPropertyEquipDao.getElevatorTempAuth(userId,projectId);
        if(StringUtils.isNotBlank(elevatorAuth)){
            elevatorAuth = StringHandlerUtil.convertAuth(elevatorAuth,"1");
            result.put("elevatorAuth",elevatorAuth);
        }
        //获取用户云对讲临时权限
        String talkAuth = iPropertyEquipDao.getCloudTalkTempAuth(userId, projectId);
        if(StringUtils.isNotBlank(talkAuth)){
            talkAuth = StringHandlerUtil.convertAuth(talkAuth,"8");
            result.put("talkAuth",talkAuth);
        }
        result.put("userId",userId);
        result.put("projectId",projectId);
        return result;
    }

    /**
     * <desc>
     *      根据电梯设备的楼层范围变更重新设置物业临时授权的用户楼层权限
     * </desc>
     *
     * @param dto
     * @author Jiaqi.X
     * @createDate 2018/07/12
     */
//    @Override
//    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
//    public void changeUserElevatorFloorAuthByDeviceFloorChange(ElevatorFloorChangeDTO dto) throws Exception {
//        //更新权限的用户id
//        Set<String> userIds = new HashSet<>();
//        //计算新老楼层起始楼层的差值
//        int dValue = 0;
//        if(dto.getOldStartFloor() >0 && dto.getNewStartFloor() <0){
//            dValue = dto.getNewStartFloor() - dto.getOldStartFloor() + 1;
//        }else if(dto.getOldStartFloor() < 0 && dto.getNewStartFloor() > 0){
//            dValue = Math.abs(dto.getNewStartFloor() + dto.getOldStartFloor() -1);
//        }else if(dto.getOldStartFloor() < 0 && dto.getNewStartFloor() < 0){
//            dValue = Math.abs(dto.getOldStartFloor()) - Math.abs(dto.getNewStartFloor());
//        }else{
//            dValue = dto.getNewStartFloor() - dto.getOldStartFloor();
//        }
//        //模拟当前最新的楼层映射表 key为权限标识 value为真实楼层 过滤不在电梯楼层范围内的用户楼层权限
//        Map<Integer,Integer> newConfig = new HashMap<>();
//        int trueFloor = dto.getNewStartFloor();
//        for(int i=1;i <= 112;i++){
//            newConfig.put(i,trueFloor);
//            if(trueFloor+1!=0){
//                trueFloor++;
//            }else{
//                trueFloor+=2;
//            }
//        }
//        //获取机号
//        int deviceId = Integer.valueOf(dto.getDeviceUnique().substring(dto.getDeviceUnique().length() - 4, dto.getDeviceUnique().length()));
//        //查询所有拥有该电梯的用户临时权限
//        List<DeviceElevatorAuthPO> list = iPropertyElevatorDao.
//                getUserAuthsByDeviceId(deviceId , dto.getProjectId());
//        for(DeviceElevatorAuthPO po : list){
//            userIds.add(po.getUserId());
//            String deviceAuth = po.getDeviceAuth();
//            //找到当前用户拥有该设备机号位置在二进制数据中为1的下标
//            int num = -1;
//            for(int i = 0 ;i < 384 ; i++){
//                if(deviceAuth.substring(i,i+1).equals("1")){
//                    num++;
//                    if((i+1)==deviceId){
//                        break;
//                    }
//                }
//            }
//            String floorAuths[] = StringHandlerUtil.splitString(po.getFloorAuth());
//            //获取更改的该机号的楼层权限
//            StringBuilder floorAuth = new StringBuilder(StringHandlerUtil.hexToBinary(floorAuths[num]));
//            boolean plusOrMinus = dValue > 0 ? true : false;
//            //更新用户的楼层权限 如果新楼层增加的数值为负数 用户楼层权限前置增加该数值个数字符串"0"
//            if(plusOrMinus) {
//                for (int i = 0; i < Math.abs(dValue); i++) {
//                    floorAuth.append("0");
//                }
//            }else{
//                for (int i = 0; i < Math.abs(dValue); i++) {
//                    floorAuth.insert(0, "0");
//                }
//            }
//            if(plusOrMinus){
//                //更新用户的楼层权限 如果新楼层增加的数值为正数 需将所有用户权限为1的楼层前移该数值的位数
//                for (int i = 0; i < 112 + Math.abs(dValue); i++) {
//                    if(floorAuth.substring(i,i+1).equals("1")){
//                        if(i-dValue>=0) {
//                            floorAuth.replace(i - dValue, i - dValue + 1, "1");
//                        }
//                        floorAuth.replace(i,i+1,"0");
//                    }
//                }
//            }
//            //删除新楼层增加数值个数的floorAuth后置字符
//            floorAuth.replace(112,112+Math.abs(dValue),"");
//            //过滤不在楼层范围内的用户楼层权限
//            for(int i=0 ; i<112 ; i++){
//                if(floorAuth.substring(i,i+1).equals("1")){
//                    int floor = newConfig.get(i+1);
//                    if(floor > dto.getNewEndFloor() || floor < dto.getNewStartFloor()){
//                        floorAuth.replace(i,i+1,"0");
//                    }
//                }
//            }
//            //判断变更楼层后用户是否还有楼层权限 如没有需清楚该用户的电梯临时授权
//            if(floorAuth.indexOf("1") < 1){
//                StringBuilder da = new StringBuilder(deviceAuth);
//                da.replace(num,num+1,"0");
//                deviceAuth = da.toString();
//            }
//            //更新完用户的楼层权限后替换掉原电梯权限及楼层权限
//            floorAuths[num]=StringHandlerUtil.binaryToHex(floorAuth.toString()).toUpperCase();
//            po.setDeviceAuth(deviceAuth);
//            po.setFloorAuth(StringUtils.join(floorAuths,","));
//            po.setProjectId(dto.getProjectId());
//            //更新用户楼层权限
//            iPropertyDeviceAuthElevatorAuthDao.update(po);
//        }
//        this.sendDeviceSmartCardChange(userIds.toArray(new String[userIds.size()]),dto.getProjectId());
//    }


    /**
     * <desc>
     *      通知app、一卡通 用户权限变更 刷新权限
     * </desc>
     *
     * @param userIds
     * @param projectId
     * @throws Exception
     * @author Jiaqi.X
     * @createDate 2018/03/17
     */
    private void sendDeviceSmartCardChange(String[] userIds,String projectId) throws Exception {
        for(String userId:userIds) {
            ipropertyDeviceAuthService.updateUserDeviceAuthAtRedis(userId,projectId,true,null);
        }
    }

    /**
     * <desc>
     *      根据项目编号修改项目下设备的配置人脸识别的状态
     * </desc>
     *
     * @param projectId 设备唯一码
     * @return
     * @author JuGuang.S
     * @createDate 2018-07-03
     */
    @Override
    public void updateEquipFaceStatus(String projectId) {
        iPropertyElevatorDao.updateEquipFaceStatus(projectId);
    }

    /**
     * <desc>
     *      设置云对讲设备的待机界面
     * </desc>
     *
     * @param deviceUniqueStr
     * @param fileUrl 文件上传服务器的URL
     * @return
     * @author JuGuang.S
     * @createDate 2018-08-07
     */
    @Override
    public void setStandbyInterface(String deviceUniqueStr, String fileUrl) throws Exception {

        List<Map<String, Object>> batchUpdateList = new ArrayList<>();
        List<DeviceBusinessChangeLogPO> deviceBusinessChangeLogPOS = new ArrayList<>();
        String[] deviceUniqueArr = deviceUniqueStr.split(",");
        for(String deviceUnique : deviceUniqueArr){
            DeviceCloudIntercomInfoPO cloudIntercomInfoPO = iDeviceCloudIntercomInfoDao.getByDeviceUnique(deviceUnique,"");
            cloudIntercomInfoPO.setStandbyImageUrl(fileUrl);
            cloudIntercomInfoPO.setUpdateTime(new Date());
            batchUpdateList.add(SqlUtil.durableData(cloudIntercomInfoPO, PlatformConstants.TABLE_UPDATE));

            JSONArray jsonArray = new JSONArray();
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("deviceUnique",cloudIntercomInfoPO.getDeviceUnique());
            jsonArray.add(jsonObject);
            deviceBusinessChangeLogPOS.add(new DeviceBusinessChangeLogPO(SmartCommunityEnum.PUSH_DEVICE, jsonArray, cloudIntercomInfoPO.getProjectId()));
        }

        //批量更新设备的待机界面的url
        if (!batchUpdateList.isEmpty()) {
            iPropertyElevatorDao.batchUpdateEquip(batchUpdateList);
        }

        if (deviceBusinessChangeLogPOS != null && !deviceBusinessChangeLogPOS.isEmpty()) {
            this.pushCloudIntercom(deviceBusinessChangeLogPOS);
        }
    }



    /**
     * <desc>
     *      向设备推送设备云对讲指令
     * <desc/>
     *
     * @param   changeLogPOS     云对讲变更指令集合
     * @author Juguang.s
     * @createDate 2018/08/07
     */
    public void pushCloudIntercom(List<DeviceBusinessChangeLogPO> changeLogPOS) throws Exception {
        // 添加硬件推送指令
        if (!changeLogPOS.isEmpty()) {
            JSONObject dataJs = new JSONObject();
            dataJs.put("data", changeLogPOS);
            //云对讲
            messageSender.send(RabbitMQConstant.RABBITMQ_HANDLE_SMART_COMMUNITY_ORDERS_QUEUE,
                    JsonUtil.toJSON(dataJs), RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_EXCHANGE,
                    RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_ROUTING_KEY);
        }
    }

    /**
     * <desc>
     * 重置电梯设备的楼层映射表
     * <desc/>
     *
     * @param deviceUniqueStr 电梯设备的deviceUnique号，多个以逗号隔开
     * @return 标准格式化响应结果
     * @author Juguang.S
     * @createDate 2018/08/21
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public void resetFloorInfo(String deviceUniqueStr,String projectId) throws Exception {
        String[] deviceUniqueArr = deviceUniqueStr.split(",");
        for(String deviceUnique : deviceUniqueArr){
            List<String> deviceList = new ArrayList<>();
            Map<String,Object> controlls = iAppDeviceDao.getControllerDeviceUniqueByElevatorDeviceUnique(deviceUnique);
            if(controlls != null && controlls.get("groupConId") != null){
                String devicesArr[] = StringHandlerUtil.splitString(controlls.get("deviceUnique").toString());
                deviceList = Arrays.asList(devicesArr);
            }else{
                deviceList.add(deviceUnique);
            }
            for(String device : deviceList) {
                Integer floorNo = iPropertyEquipDao.getMinFloorByDeviceUnique(device);
                Integer floorMax = iPropertyEquipDao.getMaxFloorByDeviceUnique(device);


                //更新电梯的楼层范围
                iPropertyEquipDao.updateFloorAround(1,
                        floorMax < 0 && floorMax == -1 ?
                                Math.abs(floorNo) :
                                floorMax < 0 && floorMax != -1 ?
                                        Math.abs(floorNo) - Math.abs(floorNo + 1) :
                                        floorNo < 0 ?
                                                Math.abs(floorNo) + floorMax :
                                                floorNo == 1 ? floorMax :
                                                        floorMax - floorNo + 1,
                        device);
                Integer negative = 0 + floorNo;
                Integer naturalFloor = 1;
                Integer terminalFloor = 1;
                Integer terminalNumIntercom = 1;
                List<DeviceElevatorFloorConfigPO> floorConfigPOList = new ArrayList<>();
                for (int i = 1; i <= PlatformConstants.MAX_ELEVATOR_FLOORNUM; i++) {
                    //负楼层在后
                    floorNo = (i == 1 && negative < 0) || floorNo == 0 ? 1 : floorNo;
                    DeviceElevatorFloorConfigPO floorConfigPO = new DeviceElevatorFloorConfigPO(floorNo, device, (naturalFloor++).toString());
                    if (floorNo > floorMax && negative < 0) {
                        floorNo = iPropertyEquipDao.getMinFloorByDeviceUnique(device);
                        floorConfigPO.setFloorNum(floorNo);
                    }
                    if (i > 1 && negative < 0 && floorNo == 1) {
                        floorNo = floorMax + 1;
                        negative = 1;
                        floorConfigPO.setFloorNum(floorNo);
                    }
                    floorConfigPO.setLogicalFloor((floorNo).toString());
                    floorConfigPO.setTerminalFloor((terminalFloor++).toString());
                    floorConfigPO.setDetectFloor((floorNo).toString());
                    floorConfigPO.setTerminalNumIntercom((terminalNumIntercom++).toString());
                    floorConfigPO.setStatus(DataStatusEnum.NORMAL.getType());
                    floorConfigPO.setCreateTime(new Date());
                    floorConfigPOList.add(floorConfigPO);
                    floorNo++;
                }

                Map<String, Object> oldFloors = new HashMap<>();
                Map<String, Object> newFloors = new HashMap<>();
                List<DeviceElevatorFloorConfigPO> configPOList = floorConfigDao.getFloorConfigIdList(device);
                for (DeviceElevatorFloorConfigPO configPO : configPOList) {
                    oldFloors.put(configPO.getNaturalFloor(), configPO.getFloorNum());
                }

                for (DeviceElevatorFloorConfigPO floorInfoDTO : floorConfigPOList) {
                    newFloors.put(floorInfoDTO.getFloorNum().toString(), floorInfoDTO.getNaturalFloor());
                }
                ElevatorFloorChangeDTO changeDTO = new ElevatorFloorChangeDTO();
                changeDTO.setProjectId(projectId);
                changeDTO.setDeviceUnique(device);
                changeDTO.setOldFloors(oldFloors);
                changeDTO.setNewFloors(newFloors);

                Map<String, Object> map = new HashMap<>();
                map.put("elevator", changeDTO);
                messageSender.send(
                        RabbitMQConstant.RABBITMQ_CHANGE_USER_ELEVATOR_FLOOR_AUTH_QUEUE,
                        JSON.toJSONString(map),
                        RabbitMQConstant.RABBITMQ_EQUIP_EXCHANGE,
                        RabbitMQConstant.RABBITMQ_CHANGE_USER_ELEVATOR_FLOOR_AUTH_KEY
                );

                floorConfigDao.delByDeviceUnique(device);
                if (!floorConfigPOList.isEmpty()) {
                    floorConfigDao.saveBatch(floorConfigPOList);
                }
                floorConfigDao.updateElevatorBracketPanel(device, 0);//恢复默认副盘标记
                //推送数据给一卡通
                prepareEquipInfoForSyncToSmartCard(projectId, JSON.toJSONString(floorConfigPOList), 2, SmartCardSyncDataOperTypeEnum.UPDATE);

                String sn = iPropertyEquipDao.getElevatorSnByDeviceUnique(device);
                if (StringUtils.isNotBlank(sn)) {
                    List<DeviceBusinessElevatorChangeLogPO> deviceBusinessElevatorChangeLogPOs = new ArrayList<>();
                    List<String> sns = new ArrayList<>();
                    sns.add(sn);
                    DeviceBusinessElevatorChangeLogPO deviceBusinessChangeLogPO = new DeviceBusinessElevatorChangeLogPO(StringHandlerUtil.getProjectIdBySn(sns.get(0)),
                            CloudElevatorChangeBusinessEnum.PUSH_FLOOR_INFO, JsonUtil.toJSON(sns));
                    deviceBusinessElevatorChangeLogPOs.add(deviceBusinessChangeLogPO);
                    this.pushElevator(deviceBusinessElevatorChangeLogPOs);
                }
            }
        }

    }


    /**
     * <desc>
     * 修改电梯设备的楼层映射表
     * <desc/>
     *
     * @param deviceUniqueStr 电梯设备的deviceUnique号
     * @return 标准格式化响应结果
     * @author Juguang.S
     * @createDate 2018/08/21
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public Map<String,Object> updateFloorInfo(String deviceUniqueStr, List<ElevatorFloorInfoDTO> elevatorFloorDTOList,String projectId,Integer bracketPanel) throws Exception {
        List<String> deviceList = new ArrayList<>();
        Map<String,Object> resultMap = new HashMap<>();
        Map<String,Object> controlls = iAppDeviceDao.getControllerDeviceUniqueByElevatorDeviceUnique(deviceUniqueStr);
        if(controlls != null && controlls.get("groupConId") != null){
            String devicesArr[] = StringHandlerUtil.splitString(controlls.get("deviceUnique").toString());
            deviceList = Arrays.asList(devicesArr);
            resultMap = iAppDeviceDao.getElevatorNameByController(controlls.get("groupConId").toString());
        }else{
            deviceList.add(deviceUniqueStr);
        }
        for(String device : deviceList) {
            Map<String, Object> oldFloors = new HashMap<>();
            Map<String, Object> newFloors = new HashMap<>();
            List<DeviceElevatorFloorConfigPO> configPOList = floorConfigDao.getFloorConfigIdList(device);
            Integer maxFloor = 0;
            Integer minFloor = 1000;
            Integer naturalMaxFloor = 0;
            Integer naturalMinFloor = 1000;
            n:for (ElevatorFloorInfoDTO floorInfoDTO : elevatorFloorDTOList) {
                o:for (int i = 0; i < configPOList.size(); i++) {
                    if (floorInfoDTO.getNaturalFloor().equals(Integer.valueOf(configPOList.get(i).getNaturalFloor()))) {
                        DeviceElevatorFloorConfigPO floorConfigPO = new DeviceElevatorFloorConfigPO();
                        floorConfigPO.setTerminalFloor(floorInfoDTO.getTerminalFloor());
                        floorConfigPO.setTerminalNumSlave1(floorInfoDTO.getTerminalNumSlave1());
                        floorConfigPO.setTerminalNumSlave2(floorInfoDTO.getTerminalNumSlave2());
                        floorConfigPO.setTerminalNumIntercom(floorInfoDTO.getTerminalFloor());
                        floorConfigPO.setLogicalFloor(floorInfoDTO.getLogicalFloor());
                        floorConfigPO.setDetectFloor(floorInfoDTO.getDetectFloor());
                        floorConfigPO.setFloorNum(Integer.valueOf(floorInfoDTO.getFloorNum()));
                        floorConfigPO.setNaturalFloor(floorInfoDTO.getNaturalFloor().toString());
                        floorConfigPO.setDeviceUnique(device);
                        floorConfigPO.setStatus(DataStatusEnum.NORMAL.getType());
                        floorConfigPO.setCreateTime(new Date());
                        floorConfigPO.setUpdateTime(new Date());
                        if (floorConfigPO.getFloorNum() < minFloor) {
                            minFloor = floorConfigPO.getFloorNum();
                        }
                        if (Integer.valueOf(floorConfigPO.getNaturalFloor()) < naturalMinFloor) {
                            naturalMinFloor = Integer.valueOf(floorConfigPO.getNaturalFloor());
                        }
                        if (Integer.valueOf(floorConfigPO.getNaturalFloor()) > naturalMaxFloor) {
                            naturalMaxFloor = Integer.valueOf(floorConfigPO.getNaturalFloor());
                        }
                        if (!floorConfigPO.getFloorNum().equals(999) && floorConfigPO.getFloorNum() > maxFloor) {
                            maxFloor = floorConfigPO.getFloorNum();
                        }
                        configPOList.set(i, floorConfigPO);
                    }
                }
            }
            Integer startFloor = elevatorFloorDTOList.get(0).getNaturalFloor();
            Integer endFloor = elevatorFloorDTOList.get(elevatorFloorDTOList.size() - 1).getNaturalFloor();
            List<DeviceElevatorFloorConfigPO> oldConfigList = iDeviceElevatorFloorConfigDao.getOldFloorConfigIdList(device,endFloor,startFloor);
            for (DeviceElevatorFloorConfigPO configPO : oldConfigList) {
                oldFloors.put(configPO.getNaturalFloor(), configPO.getFloorNum());
                Optional<ElevatorFloorInfoDTO> elevator = elevatorFloorDTOList.stream().filter(dto ->
                        dto.getNaturalFloor().toString().equals(configPO.getNaturalFloor())).findFirst();
                if (elevator.isPresent()) {
                    newFloors.put(elevator.get().getFloorNum().toString(), elevator.get().getNaturalFloor());
                } else {
                    newFloors.put(configPO.getFloorNum().toString(), configPO.getNaturalFloor());
                }
            }
            List<DeviceElevatorFloorConfigPO> removeList = new ArrayList<>();
            for (int i = startFloor - 1; i <= endFloor - 1; i++) {
                removeList.add(configPOList.get(i));
            }
            remove:
            for (DeviceElevatorFloorConfigPO remove : removeList) {
                config:
                for (DeviceElevatorFloorConfigPO config : configPOList) {
                    if (!remove.getNaturalFloor().equals(config.getNaturalFloor())) {
                        //端子号
                        if (!config.getTerminalFloor().equals("-") && remove.getTerminalFloor().equals(config.getTerminalFloor())) {
                            config.setTerminalFloor("-");
                            config.setTerminalNumIntercom("-");
                            break config;
                        }
                        //检测楼层
                        if (!config.getDetectFloor().equals("-") && remove.getDetectFloor().equals(config.getDetectFloor())) {
                            config.setDetectFloor("-");
                            break config;
                        }
                        //按键名称
                        if (!config.getLogicalFloor().equals("未定义") && remove.getLogicalFloor().equals(config.getLogicalFloor())) {
                            config.setLogicalFloor("未定义");
                            break config;
                        }
                        //真实楼层
                        if (!config.getFloorNum().equals(999) && remove.getFloorNum().equals(config.getFloorNum())) {
                            config.setFloorNum(999);
                            break config;
                        }
                    }
                }
            }
            //获取电梯公共楼层
            String commonFloor = floorConfigDao.getCommonFloorByDeviceUnique(device);
            if (StringUtils.isNotBlank(commonFloor)) {
                String[] commonFloors = StringHandlerUtil.splitString(commonFloor);
                StringBuilder cf = new StringBuilder();
                for (String f : commonFloors) {
                    if (Integer.valueOf(f) >= minFloor && Integer.valueOf(f) <= maxFloor) {
                        cf.append(f + ",");
                    }
                }
                if (cf.length() > 0) {
                    commonFloor = cf.substring(0, cf.length() - 1);
                } else {
                    commonFloor = cf.toString();
                }
                //更新公共楼层
                iDeviceElevatorFloorConfigDao.updateCommonFloor(device, commonFloor);
            }
            floorConfigDao.updateElevatorBracketPanel(device, bracketPanel);//更新副盘标记
            //清除楼层映射表内副盘字段
            floorConfigDao.updateElevatorTerminal(device);
            //更新电梯最大最小楼层
            iDeviceElevatorFloorConfigDao.updateElevatorMaxAndMinFloor(device, naturalMaxFloor, naturalMinFloor);
            iDeviceElevatorFloorConfigDao.updateBatch(configPOList);
            //推送数据给一卡通
            DeviceElevatorInfoPO deviceElevatorInfoPO = iPropertyEquipDao.getElevatorByDeviceUnique(device);
            List<DeviceElevatorInfoPO> deviceInfoPOS = new ArrayList();
            deviceInfoPOS.add(deviceElevatorInfoPO);
            //发送数据更改楼层范围
            prepareEquipInfoForSyncToSmartCard(projectId, JSON.toJSONString(deviceInfoPOS), 1, SmartCardSyncDataOperTypeEnum.UPDATE);
            //推送数据给一卡通
            prepareEquipInfoForSyncToSmartCard(projectId, JSON.toJSONString(configPOList), 2, SmartCardSyncDataOperTypeEnum.UPDATE);
            //推送云电梯
            String sn = iPropertyEquipDao.getElevatorSnByDeviceUnique(device);
            if (StringUtils.isNotBlank(sn)) {
                List<DeviceBusinessElevatorChangeLogPO> deviceBusinessElevatorChangeLogPOs = new ArrayList<>();
                List<String> sns = new ArrayList<>();
                sns.add(sn);
                DeviceBusinessElevatorChangeLogPO deviceBusinessChangeLogPO = new DeviceBusinessElevatorChangeLogPO(StringHandlerUtil.getProjectIdBySn(sns.get(0)),
                        CloudElevatorChangeBusinessEnum.PUSH_FLOOR_INFO, JsonUtil.toJSON(sns));
                deviceBusinessElevatorChangeLogPOs.add(deviceBusinessChangeLogPO);
                this.pushElevator(deviceBusinessElevatorChangeLogPOs);
            }
            ElevatorFloorChangeDTO changeDTO = new ElevatorFloorChangeDTO();
            changeDTO.setProjectId(projectId);
            changeDTO.setDeviceUnique(device);
            changeDTO.setOldFloors(oldFloors);
            changeDTO.setNewFloors(newFloors);
            Map<String, Object> map = new HashMap<>();
            map.put("elevator", changeDTO);
            messageSender.send(
                    RabbitMQConstant.RABBITMQ_CHANGE_USER_ELEVATOR_FLOOR_AUTH_QUEUE,
                    JSON.toJSONString(map),
                    RabbitMQConstant.RABBITMQ_EQUIP_EXCHANGE,
                    RabbitMQConstant.RABBITMQ_CHANGE_USER_ELEVATOR_FLOOR_AUTH_KEY
            );
        }
        return resultMap;
    }

    /**
     * <desc>
     *      快速设置楼层映射表
     * </desc>
     *
     * @param startFloor
     * @param startTerminal
     * @param deviceUnique
     * @param type 1端子号 2检测楼层 3按键名称
     * @author Jiaqi.X
     * @createDate 2018/11/26
     */
    @Override
    @Transactional(rollbackFor = Exception.class ,propagation = Propagation.REQUIRED)
    public void floorFastSetting(String startFloor,String endFloor,String startTerminal,String deviceUnique,Integer type) throws Exception {
        List<String> deviceList = new ArrayList<>();
        Map<String,Object> controlls = iAppDeviceDao.getControllerDeviceUniqueByElevatorDeviceUnique(deviceUnique);
        if(controlls != null && controlls.get("groupConId") != null){
            String devicesArr[] = StringHandlerUtil.splitString(controlls.get("deviceUnique").toString());
            deviceList = Arrays.asList(devicesArr);
        }else{
            deviceList.add(deviceUnique);
        }
        for(String device : deviceList) {
            List<DeviceElevatorFloorConfigPO> configPOList = floorConfigDao.getFloorConfigIdList(device);
            //获取电梯信息得到最大实际楼层
            Integer maxFloor = iPropertyEquipDao.getMaxFloorByDeviceUnique(device);
            Integer terminal = Integer.valueOf(startTerminal);
            for (int i = Integer.valueOf(startFloor) - 1; i <= Integer.valueOf(endFloor) - 1; i++) {
                if (type == 1) {
                    if (terminal < 113) {
                        configPOList.get(i).setTerminalFloor(terminal.toString());
                        configPOList.get(i).setTerminalNumIntercom(terminal.toString());
                    } else {

                        break;
                    }
                    terminal++;
                } else {
                    if (terminal == 0) {
                        terminal++;
                    }
                    if (terminal <= maxFloor) {
                        if (type == 2) {
                            configPOList.get(i).setDetectFloor(terminal.toString());
                        } else {
                            configPOList.get(i).setLogicalFloor(terminal.toString());
                        }
                    }
                    terminal++;
                }
            }
            List<DeviceElevatorFloorConfigPO> removeList = new ArrayList<>();
            for (int i = Integer.valueOf(startFloor) - 1; i <= Integer.valueOf(endFloor) - 1; i++) {
                removeList.add(configPOList.get(i));
            }
            remove:
            for (DeviceElevatorFloorConfigPO remove : removeList) {
                config:
                for (DeviceElevatorFloorConfigPO config : configPOList) {
                    if (!remove.getNaturalFloor().equals(config.getNaturalFloor())) {
                        if (type == 1) {
                            //端子号
                            if (!config.getTerminalFloor().equals("-") && remove.getTerminalFloor().equals(config.getTerminalFloor())) {
                                config.setTerminalFloor("-");
                                config.setTerminalNumIntercom("-");
                                break config;
                            }
                        } else if (type == 2) {
                            //检测楼层
                            if (!config.getDetectFloor().equals("-") && remove.getDetectFloor().equals(config.getDetectFloor())) {
                                config.setDetectFloor("-");
                                break config;
                            }
                        } else if (type == 3) {
                            //按键名称
                            if (!config.getLogicalFloor().equals("-") && remove.getLogicalFloor().equals(config.getLogicalFloor())) {
                                config.setLogicalFloor("-");
                            }
                        }
                    }
                }
            }
            iDeviceElevatorFloorConfigDao.updateBatch(configPOList);
            String sn = iPropertyEquipDao.getElevatorSnByDeviceUnique(device);
            if (StringUtils.isNotBlank(sn)) {
                //推送数据给一卡通
                prepareEquipInfoForSyncToSmartCard(StringHandlerUtil.getProjectIdByDeviceUnique(device), JSON.toJSONString(configPOList), 2, SmartCardSyncDataOperTypeEnum.UPDATE);
                List<DeviceBusinessElevatorChangeLogPO> deviceBusinessElevatorChangeLogPOs = new ArrayList<>();
                List<String> sns = new ArrayList<>();
                sns.add(sn);
                DeviceBusinessElevatorChangeLogPO deviceBusinessChangeLogPO = new DeviceBusinessElevatorChangeLogPO(StringHandlerUtil.getProjectIdBySn(sns.get(0)),
                        CloudElevatorChangeBusinessEnum.PUSH_FLOOR_INFO, JsonUtil.toJSON(sns));
                deviceBusinessElevatorChangeLogPOs.add(deviceBusinessChangeLogPO);
                this.pushElevator(deviceBusinessElevatorChangeLogPOs);
            }
        }
    }

    /**
     * <desc>
     * 楼层映射表发生变化后向用户发送消息队列
     * <desc/>
     *
     * @author Juguang.S
     * @createDate 2018/08/28
     */
    public void modifyFloorConfigInfoSendMessage(String deviceUniqueStr,List<ElevatorFloorInfoDTO> elevatorFloorDTOList,String projectId) throws Exception {
        Map<String,Object> oldFloors = new HashMap<>();
        Map<String,Object> newFloors = new HashMap<>();
        List<DeviceElevatorFloorConfigPO> configPOList = floorConfigDao.getFloorConfigIdList(deviceUniqueStr);
        for(DeviceElevatorFloorConfigPO configPO : configPOList){
            oldFloors.put(configPO.getTerminalFloor(),configPO.getFloorNum());
        }

        for(ElevatorFloorInfoDTO floorInfoDTO : elevatorFloorDTOList){
            newFloors.put(floorInfoDTO.getFloorNum().toString(),floorInfoDTO.getTerminalFloor());
        }
        ElevatorFloorChangeDTO changeDTO = new ElevatorFloorChangeDTO();
        changeDTO.setProjectId(projectId);
        changeDTO.setDeviceUnique(deviceUniqueStr);
        changeDTO.setOldFloors(oldFloors);
        changeDTO.setNewFloors(newFloors);

        Map<String, Object> map = new HashMap<>();
        map.put("elevator", changeDTO);
        messageSender.send(
                RabbitMQConstant.RABBITMQ_CHANGE_USER_ELEVATOR_FLOOR_AUTH_QUEUE,
                JSON.toJSONString(map),
                RabbitMQConstant.RABBITMQ_EQUIP_EXCHANGE,
                RabbitMQConstant.RABBITMQ_CHANGE_USER_ELEVATOR_FLOOR_AUTH_KEY
        );
    }


    /**
     * <desc>
     * 根据deviceUnique获取电梯设备的楼层映射信息
     * <desc/>
     *
     * @param deviceUniqueStr 电梯设备的deviceUnique号
     * @return 标准格式化响应结果
     * @author Juguang.S
     * @createDate 2018/08/21
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public List<CloudElevatorFloorInfoVO> getElevatorFloorInfo(String deviceUniqueStr) throws Exception {
        //获取楼层范围内的最大权限标识和最小权限标识
        DeviceElevatorInfoPO po = iPropertyEquipDao.getElevatorByDeviceUnique(deviceUniqueStr);
        Map<String,Object> map =  iPropertyEquipDao.getMaxNaturalAndMinNatural(deviceUniqueStr);
        return floorConfigDao.getFloorInfoList(deviceUniqueStr,map.get("maxNaturalFloor").toString(),map.get("minNaturalFloor").toString());

    }


    /**
     * <desc>
     *       重置/修改电梯楼层映射表时，推送映射表信息给一卡通
     * <desc/>
     *
     * @param projectId        操作的所属项目ID
     * @param data             操作的电梯楼层映射表信息
     * @param operateEquipType 操作类型 添加或更新
     * @author Juguang.S
     * @createDate 2018/08/21
     */
    public void prepareEquipInfoForSyncToSmartCard(String projectId, String data,Integer type, SmartCardSyncDataOperTypeEnum operateEquipType) throws Exception {
        //打包
        SmartCardSyncDataPullDTO smartCardSyncDataPullDTO;
        if(type == 1){
            smartCardSyncDataPullDTO = new SmartCardSyncDataPullDTO(projectId, data, operateEquipType,
                    SmartCardSyncDataTypeEnum.EQUIP_DATA);
        }else{
            smartCardSyncDataPullDTO =  new SmartCardSyncDataPullDTO(projectId, data, operateEquipType,
                    SmartCardSyncDataTypeEnum.FLOOR_RELATION_DATA);
        }

        //发送
        JSONObject dataJs = new JSONObject();
        dataJs.put("data",JSONObject.toJSON(smartCardSyncDataPullDTO));
        messageSender.send(RabbitMQConstant.RABBITMQ_SMARTCARD_SAVE_MODIFY_QUEUE, JsonUtil.toJSON(dataJs),
                RabbitMQConstant.RABBITMQ_SMARTCARD_SAVE_EXCHANGE, RabbitMQConstant.RABBITMQ_SMARTCARD_SAVE_MODIFY_ROUTING_KEY);
    }

    /**
     * <desc>
     *      获取楼栋的地上及地下楼层
     * </desc>
     *
     * @param buildId
     * @return
     * @author Jiaqi.X
     * @createDate 2018/12/18
     */
    public Map<String,Object> getBuildMaxFloorAndMinFloor(String buildId){
        return iPropertyEquipDao.getBuildMaxFloorAndMinFloor(buildId);
    }

    /**
     * <desc>
     *      获取最大权限标识及最小权限标识
     * </desc>
     *
     * @param deviceUnique
     * @return
     * @author Jiaqi.X
     * @createDate 2018/12/18
     */
    public Map<String,Object> getMaxNaturalAndMinNatural(String deviceUnique){
        return iPropertyEquipDao.getMaxNaturalAndMinNatural(deviceUnique);
    }

    /**
     * <desc>
     *      查询云电梯楼层映射信息
     * </desc>
     *
     * @param deviceUnique 设备序列号
     * @return 云电梯楼层映射信息
     * @author wangzhi
     * @createDate 2019/01/21
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public PropertyDeviceElevatorConfigVO getDeviceElevatorConfig(String deviceUnique) throws Exception {
        return iDeviceElevatorFloorConfigDao.getDeviceElevatorConfig(deviceUnique);
    }

    /**
     * <desc>
     *      楼层映射表调整
     * </desc>
     *
     * @author Jiaqi.X
     * @createDate 2019/03/27
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public void floorMappingTrim() {
        List<PropertyFloorMappingTrimDTO> elevators = iPropertyEquipDao.getElevatorFloorInfos();
        for (PropertyFloorMappingTrimDTO elevator : elevators) {
            elevator.setFloorNo(1);
            elevator.setFloorNoMax(elevator.getEndNaturalFloor());
            iPropertyEquipDao.updateFloorMappingTrim(elevator);
        }
    }

    /**
     * <desc>
     *     兼容之前添加门禁设备的门禁类别
     * </desc>
     *
     * @author Juguang.S
     * @createDate 2019/02/21
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public void handleOldDataEntranceType() throws Exception {
        List<DeviceEntranceInfoPO> list = iDeviceEntranceInfoDao.getEntranceInfo();
        List<Map<String, Object>> updateEntranceList = new ArrayList<>();
        for(DeviceEntranceInfoPO infoPO : list){
            infoPO.setUpdateTime(new Date());
            //infoPO.setSn(String.format("%s%s%04d", infoPO.getProjectId(), "0000", Integer.parseInt(infoPO.getDeviceId())));
            //根据deviceUnique查询这个设备归属信息进行判断设备类型
            List<DeviceEntranceBridgeInfoPO> bridgeInfoPOList = iDeviceEntranceBridgeInfoDao.getAddress(infoPO.getDeviceUnique());
            if(bridgeInfoPOList!=null && !bridgeInfoPOList.isEmpty()){
                DeviceEntranceBridgeInfoPO bridgeInfoPO = bridgeInfoPOList.get(0);
                if(StringUtils.isNotEmpty(bridgeInfoPO.getBuildId()) && StringUtils.isNotEmpty(bridgeInfoPO.getUnitId())){
                    infoPO.setEntranceType(EntranceTypeEnum.UNIT_ENTRANCE.getType());
                }
                if(StringUtils.isNotEmpty(bridgeInfoPO.getBuildId()) && StringUtils.isEmpty(bridgeInfoPO.getUnitId())){
                    infoPO.setEntranceType(EntranceTypeEnum.BUILD_ENTRANCE.getType());
                }
                updateEntranceList.add(SqlUtil.durableData(infoPO,PlatformConstants.TABLE_UPDATE));
            }

        }
        iDeviceEntranceInfoDao.batchUpdateDeviceEntranceInfo(updateEntranceList);
    }

    /**
     * <desc>
     *      云门禁上报设备的能力集信息
     * </desc>
     *
     * @param sn
     * @param capacitySet 能力集信息
     * @param doorCount 门数
     * @return
     * @author Juguang.S
     * @createDate 2019/02/22
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.NOT_SUPPORTED)
    public void reportCapacitySet(String sn, String capacitySet, int doorCount,String deviceType) throws Exception {
        JSONObject capacitySetObject = (JSONObject) JSONObject.parse(capacitySet);

        //根据sn查询以该sn作为控制器的设备
        List<String> oldSnList = iDeviceEntranceInfoDao.getSnbyBingDeviceGroup(sn);
        String version = capacitySetObject.getString("version");
        Boolean hasScreen = capacitySetObject.getBoolean("screen");
        String deviceAttributes = capacitySetObject.getString("deviceAttributes");
        String mac = capacitySetObject.getString("mac");
        String cmdList = capacitySetObject.getString("cmdList");
        List<String> snList = StringHandlerUtil.getSnByDoorNum(sn,doorCount);
        Map<String,Object> params = new HashMap<>();
        params.put("version",version);
        params.put("sn",sn);
        if(hasScreen){
            params.put("screen",1);
        }else{
            params.put("screen",0);
        }
        params.put("snList",snList);
        params.put("mac",mac);
        params.put("cmdList",cmdList);
        params.put("deviceAttributes",deviceAttributes);
        //获取产品类型具体代码
        switch(deviceType){
            //分体云门禁
            case "17":
                deviceType  =  "2";
                break;
            //一体式云门禁
            case "18":
                deviceType  =  "7";
                break;
            //联动器
            case "22":
                deviceType  =  "4";
                break;
            //一体式人脸识别门禁
            case "24":
                deviceType  =  "6";
                break;
        }

        String  productCode  =  iDeviceEntranceInfoDao.getProductCode(deviceType,deviceAttributes);
        params.put("productCode",productCode);
        String  status   =   iDeviceEntranceInfoDao.getEntranceDeviceExist(sn);
        if(StringUtils.isNotEmpty(status)){
            //更新设备主表
            iDeviceEntranceInfoDao.updateEntranceInfo(params);
        }else{
            //更新特殊设备表
            iDeviceEntranceInfoDao.updateSpecialEntranceInfo(params);
        }
        if(oldSnList != null && !oldSnList.isEmpty()){
            if(oldSnList.size()>snList.size()){
                List<String> different = new ArrayList<>();
                Map<String,Integer> map = new HashMap<>(oldSnList.size());
                for (String department : oldSnList) {
                    map.put(department, 1);
                }
                for (String department : snList) {
                    if(map.get(department)!=null)
                    {
                        map.put(department, 2);
                        continue;
                    }
                    different.add(department);
                }
                for(Map.Entry<String, Integer> entry:map.entrySet())
                {
                    if(entry.getValue()==1)
                    {
                        different.add(entry.getKey());
                    }
                }
                //处理控制器控制门数减少时的bindDeviceGroup信息
                for(String snDifferent : different){
                    iDeviceEntranceInfoDao.updateBindDeviceGroup(snDifferent);
                }
            }
        }
    }

    /**
     * <desc>
     *      云门禁获取固定密码
     * </desc>
     *
     * @param dto
     * @return
     * @author Juguang.S
     * @createDate 2019/02/22
     */
    @Override
    public CloudEntranceRoomPwdPageVO pullDevicePwd(CloudEntrancePageDTO dto) throws Exception {
        //将DTO转换为Map params
        Map<String, Object> params = SqlUtil.convertBeanToMapParams(dto);
        //分页类默认pageSize为20
        Page<CloudEntranceRoomPwdVO> page = new Page<>(dto.getPage().toString(), dto.getPageSize().toString());
        params.put("currentPage", page.getPage().getStartSlip());
        params.put("pageSize", page.getPage().getPageSize());
        List<String> snList = null;
        if(dto.getDoorNum()==0){
            snList = StringHandlerUtil.getSnByDoorNum(dto.getSn(), dto.getDoorCount());
        }else{
            snList = new ArrayList<>();
            snList.add(String.format("%s%04d",dto.getSn().substring(0,12),dto.getDoorNum()));
        }
        params.put("snList", snList);
        List<CloudEntranceRoomPwdVO> list = iDeviceEntranceInfoDao.getPullDevicePwdPage(params);
        for (CloudEntranceRoomPwdVO roomPwdVO : list) {
            Integer count = iDeviceEntranceInfoDao.getUserIsFrost(dto.getSn().substring(0, 8), roomPwdVO.getRoomId());
            if (count > 0) {
                roomPwdVO.setOpenPwd("");
            }
        }
        page.setRows(list, iDeviceEntranceInfoDao.getPullDevicePwdPageCount(params));
        CloudEntranceRoomPwdPageVO cloudEntranceRoomPwdPageVO = new CloudEntranceRoomPwdPageVO();
        cloudEntranceRoomPwdPageVO.setDevicePwdArr(page.getRows());
        cloudEntranceRoomPwdPageVO.setTotal(page.getPage().getTotalNumber());
        cloudEntranceRoomPwdPageVO.setCurrentTotal(page.getPage().getPageSize());
        cloudEntranceRoomPwdPageVO.setHaveNext(page.getPage().getTotalPage() - page.getPage().getCurrentPage() > 0 ? 1 : 0);
        return cloudEntranceRoomPwdPageVO;
    }

    /**
     * <desc>
     *      云门禁校验动态开门密码
     * </desc>
     *
     * @return false-失败 true-成功
     * @author wangzhi
     * @createDate 2019/02/25
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public Boolean checkDynamicPwd(CloudIntercomDynamicPwdCheckDTO checkDTO) throws Exception {
        String deviceId = StringHandlerUtil.formatStrLen(checkDTO.getDoorNum(), "0", 4, false, false);
        String deviceUnique = StringHandlerUtil.getProjectIdBySn(checkDTO.getSn()) + "2" + deviceId;
        DeviceEntranceInfoPO entrance = iPropertyEquipDao.getEntranceByDeviceUnique(deviceUnique);
        if (entrance == null) {
            return false;
        }
        // 1.校验动态密码
        AppVisitorPassCodeRecordPO passCode = iPropertyEquipDao.checkDynamicPwd(StringHandlerUtil.getProjectIdBySn(entrance.getSn()), checkDTO.getDynamicPwd(), entrance.getDeviceId());
        if (passCode == null) {
            return false;
        }
        boolean pushBlackList = false;
        //3.增加动态密码已使用次数
        if(iPropertyEquipDao.checkEquipMode(entrance.getDeviceUnique(),2) > 0) {
            QrcodePassUserInfoVO vo = iPropertyEquipDao.findRoomQrcodeInfoByPassId(passCode.getPassId());
            if (vo != null) {
                if (vo.getChargeMode() != null && vo.getChargeMode() == 2
                        && vo.getRoomChargeMode() != null && vo.getRoomChargeMode() == 1
                        && ((vo.getUsableCount() !=null && vo.getUsableCount() <= 0) || vo.getUsableCount() ==null)) {
                    return false;
                }
                //更新访客使用次数
                iPropertyEquipDao.udpateAppVisitorUseNum(vo.getUserId());
                //更新业主房间次数
                if (vo.getChargeMode() != null && vo.getChargeMode() == 2
                        && vo.getRoomChargeMode() != null && vo.getRoomChargeMode() == 1) {
                    if (StringUtils.isNotBlank(vo.getQrcodeBatchRecordId())) {
                        Integer row = iPropertyEquipDao.updateQrcodeRoomCount(vo.getQrcodeBatchRecordId(), vo.getUsableCount() > 1 ? 1 : 0);
                        if (row < 1 || vo.getUsableCount() == 1) {
                            //推送黑名单数据
                            pushBlackList = true;
                        }
                    }
                }
            }
        }
        // 2.生成动态密码通行记录
        TimeTaskDevicePassRecordPO po = new TimeTaskDevicePassRecordPO();
        po.setPdId(LogicIdUtil.bussinessId());
        po.setProjectId(StringHandlerUtil.getProjectIdBySn(entrance.getSn()));
        po.setDeviceType(PropertyEquipTypeEnum.CLOUD_ENTRANCE.getType());
        po.setDeviceUnique(entrance.getDeviceUnique());
        po.setDeviceName(entrance.getDeviceName());
        po.setOpenType(OpenTypeEnum.BY_DYNAMIC_PASSWORD.getType());
        po.setRoomNum(iCloudElevatorDao.getRoomNumByRoomId(passCode.getRoomId()));
        po.setPassTime(new Date());
        po.setUploadTime(new Date());
        po.setIsOpen(0);
        po.setSynchro(0);
        po.setDynamicPassword(checkDTO.getDynamicPwd());
        po.setStatus(DataStatusEnum.NORMAL.getType());
        po.setCreateTime(new Date());
        iAppDevicePassRecordDao.save(SqlUtil.durableData(po, PlatformConstants.TABLE_SAVE));
        if(pushBlackList){
            String projectId = StringHandlerUtil.getProjectIdBySn(checkDTO.getSn());
            //推送数据
            //推送黑名单更新数据
            List<DeviceBusinessChangeLogPO> changes = new ArrayList<>();
            List<DeviceBusinessElevatorChangeLogPO> elevatorChanges = new ArrayList<>();
            List<DeviceBusinessEntranceChangeLogPO> entranceChanges = new ArrayList<>();
            Map<String,Object> blackList = new HashMap<>();
            blackList.put("projectId", projectId);
            blackList.put("roomId", passCode.getRoomId());
            blackList.put("version",0);
            DeviceBusinessChangeLogPO talkPO = new DeviceBusinessChangeLogPO(SmartCommunityEnum.PUSH_BLACK_LIST, JsonUtil.toJSON(blackList), projectId);
            changes.add(talkPO);
            DeviceBusinessElevatorChangeLogPO elevatorPo = new DeviceBusinessElevatorChangeLogPO(projectId, CloudElevatorChangeBusinessEnum.PUSH_BLACK_LIST, JsonUtil.toJSON(blackList));
            elevatorChanges.add(elevatorPo);
            DeviceBusinessEntranceChangeLogPO entrancePO = new DeviceBusinessEntranceChangeLogPO(projectId, CloudEntranceChangeBusinessEnum.PUSH_BLACK_LIST, JsonUtil.toJSON(blackList));
            entranceChanges.add(entrancePO);
            JSONObject pushJs = new JSONObject();
            pushJs.put("data", changes);
            //发送云对讲业务指令
            messageSender.send(RabbitMQConstant.RABBITMQ_HANDLE_SMART_COMMUNITY_ORDERS_QUEUE, JsonUtil.toJSON(pushJs), RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_EXCHANGE, RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_ROUTING_KEY);
            pushJs.put("data", elevatorChanges);
            //推送云电梯业务指令
            messageSender.send(
                    RabbitMQConstant.RABBITMQ_HANDLE_CLOUD_ELEVATOR_CHANGE_BUSINESS_QUEUE,
                    JsonUtil.toJSON(pushJs),
                    RabbitMQConstant.RABBITMQ_CLOUD_ELEVATOR_CHANGE_BUSINESS_EXCHANGE,
                    RabbitMQConstant.RABBITMQ_CLOUD_ELEVATOR_CHANGE_BUSINESS_ROUTING_KEY);
            //发送云门禁业务指令
            pushJs.put("data", entranceChanges);
            messageSender.send(
                    RabbitMQConstant.RABBITMQ_HANDLE_CLOUD_ENTRANCE_CHANGE_BUSINESS_QUEUE,
                    JSON.toJSONString(pushJs),
                    RabbitMQConstant.RABBITMQ_CLOUD_ENTRANCE_CHANGE_BUSINESS_EXCHANGE,
                    RabbitMQConstant.RABBITMQ_CLOUD_ENTRANCE_CHANGE_BUSINESS_ROUTING_KEY
            );
        }
        return true;
    }

    /**
     * <desc>
     *      查询指定电梯是否关联云群控器
     * </desc>
     *
     * @param deviceUnique 设备序列号
     * @return
     * @author Juguang.S
     * @createDate 2019/03/26
     */
    @Override
    public Integer isBindCloudController(String deviceUnique) {
        return iPropertyEquipDao.isBindCloudController(deviceUnique);
    }

    /**
     * <desc>
     *      获取云门禁设备服务权限信息
     * </desc>
     *
     * @author wangzhi
     * @createDate 2019/04/30
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public Page<CloudEntranceDeviceAuthVO.Room> getDeviceServeRoomsByPage(CloudIntercomDeviceAuthGetDTO getDTO) {
        String elapsedtime = "getDeviceServeRoomsByPage【分页获取设备服务房间impl】开始执行：" + DateUtil.fomatDate1(new Date());
        try {
            elapsedtime += ";retrieve开始执行：" + DateUtil.fomatDate1(new Date());
            String deviceUnique = StringHandlerUtil.getEntranceDeviceUniqueBySn(getDTO.getSn());
            if ("0".equals(getDTO.getDoorNum()) && getDTO.getDoorCount() >= 2) {
                int deviceIdInt = StringHandlerUtil.strToIntDef(StringHandlerUtil.getDeviceIdBySn(getDTO.getSn()), -1);
                if (deviceIdInt == -1) {
                    return null;
                }
                String sn = getDTO.getSn();
                for (int i = 2; i <= getDTO.getDoorCount(); i++) {
                    String deviceId = StringHandlerUtil.formatStrLen((deviceIdInt + i - 1) + "", "0", 4, false, false);
                    getDTO.setSn(getDTO.getSn() + "," + sn.substring(0, sn.length() - 4) + deviceId);
                }
            } else {
                String sn = getDTO.getSn();
            getDTO.setSn(getDTO.getSn().substring(0, sn.length() - 4) + StringHandlerUtil.formatStrLen(getDTO.getDoorNum(), "0", 4, false, false));
        }
            Page<CloudEntranceDeviceAuthVO.Room> page = new Page<>();
            //1.分页获取云对讲服务的房间列表
            page.getPage().setCurrentPage((getDTO==null || getDTO.getPage()==null)?"0":getDTO.getPage().toString());
            page.getPage().setPageSize((getDTO==null || getDTO.getPageSize()==null)?"100":getDTO.getPageSize().toString());

            elapsedtime +=";getServeRoomsPage开始执行：" + DateUtil.fomatDate1(new Date());
            List<CloudEntranceDeviceAuthVO.Room> rooms =
                    iCloudEntranceDao.getServeRoomsPage(StringHandlerUtil.splitStringList(getDTO.getSn()),
                            StringHandlerUtil.getProjectIdByDeviceUnique(deviceUnique),
                            page.getPage().getStartSlip(), page.getPage().getPageSize());

            elapsedtime += ";getServeRoomsCount开始执行：" + DateUtil.fomatDate1(new Date());
            Integer count = iCloudEntranceDao.getServeRoomsCount(StringHandlerUtil.splitStringList(getDTO.getSn()),StringHandlerUtil.getProjectIdByDeviceUnique(deviceUnique));
            //填充返回数据集
            page.setRows(rooms, count);
            return page;
        } finally {
            elapsedtime += ";getDeviceServeRoomsByPage【分页获取设备服务房间impl】执行结束：" + DateUtil.fomatDate1(new Date());
            LOG.info(elapsedtime);
        }
    }

    /**
     * <desc>
     *      根据设备信息获取访客信息
     * </desc>
     *
     * @author wangzhi
     * @createDate 2019/04/30
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public List<CloudIntercomVisitorVO> getVisitorInfoByDevice(CloudIntercomDeviceAuthGetDTO getDTO) throws Exception {
        if ("0".equals(getDTO.getDoorNum()) && getDTO.getDoorCount() >= 2) {
            int deviceIdInt = StringHandlerUtil.strToIntDef(StringHandlerUtil.getDeviceIdBySn(getDTO.getSn()), -1);
            if (deviceIdInt == -1) {
                return null;
            }
            String sn = getDTO.getSn();
            for (int i = 2; i <= getDTO.getDoorCount(); i++) {
                String deviceId = StringHandlerUtil.formatStrLen((deviceIdInt + i - 1) + "", "0", 4, false, false);
                getDTO.setSn(getDTO.getSn() + "," + sn.substring(0, sn.length() - 4) + deviceId);
            }
        } else {
            String sn = getDTO.getSn();
            getDTO.setSn(getDTO.getSn().substring(0, sn.length() - 4) + StringHandlerUtil.formatStrLen(getDTO.getDoorNum(), "0", 4, false, false));
        }
        return iCloudEntranceDao.getVisitorInfoByDevice(StringHandlerUtil.splitStringList(getDTO.getSn()));
    }

    /**
     * <desc>
     *      获取项目配置的设置限制数量
     * <desc/>
     * @param   projectId   项目编号
     * @return
     * @author Juguang.S
     * @createDate 2019/08/05
     */
    @Override
    public Map<String,Object> getDeviceCountByProjectId(String projectId){
        return iPropertyEquipDao.getDeviceCountByProjectId(projectId);
    }

    /**
     * <desc>
     *      根据设备类型查询相对应设备的数量
     * <desc/>
     * @param   deviceType   设备类型 1电梯 2门禁 3电梯 4平板
     * @param   projectId    项目编号
     * @return
     * @author Juguang.S
     * @createDate 2019/08/05
     */
    @Override
    public Integer getDeviceCountByType(Integer deviceType,String projectId,String batchNumber) {
        Integer count = 0;
        switch (PropertyEquipTypeEnum.getByEquipType(deviceType)) {
            case ELEVATOR:
                count = iPropertyEquipDao.getElevatorCount(projectId,batchNumber);
                break;
            case ENTRANCE:
                count = iPropertyEquipDao.getEntranceCount(projectId,batchNumber);
                break;
            case CLOUD_INTERCOM:
                count = iPropertyEquipDao.getCouldIntercomCount(projectId,batchNumber);
                break;
            default:
                break;
        }
        if(deviceType==4){
            count = iPropertyEquipDao.getPadCount(projectId,batchNumber);
        }
        return count;
    }

    /**
     * <desc>
     *      判断一卡通是否需要注册iot
     * </desc>
     *
     * @param projectId 项目编号
     * @author Qiang.S
     * @createDate 2019/07/25
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public CloudElevatorVO checkSmartCardIot(String projectId) {
        CloudElevatorVO vo = iSmartCardFaceDao.getSmartCardIotInfo(projectId);
        try {
            if (vo != null && vo.getIotDeviceSecret() == null) {
                Map<String, Object> params = new HashMap<>();
                params.put("deviceOperateIotType", DeviceIotEnum.REGIST_DEVICE.getCommandType());
                params.put("productKey", smartCardIotProductKey);
                params.put("deviceUnique", projectId);
                Map<String, Object> result = new HashMap<>();
                result.put("data", params);
                messageSender.send(RabbitMQConstant.RABBITMQ_DEVICE_ELEVATOR_QUEUE, JsonUtil.toJSON(result),
                        RabbitMQConstant.RABBITMQ_DEVICE_ELEVATOR_EXCHANGE, RabbitMQConstant.RABBITMQ_DEVICE_ELEVATOR_KEY);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return vo;
    }


    /**
     * <desc>
     * 获取不同设备的批次号。
     * <desc/>
     *
     * @param projectId  项目ID
     * @param deviceType 设备类型1-电梯 2-门禁 3-云对讲 4-平板
     * @return
     * @author Juguang.S
     * @createDate 2019-11-21
     */
    @Override
    public List<String> getBatchNumber(String projectId, String deviceType) throws Exception {
        Set<String> set = new HashSet();
        List<String> listRemove = new ArrayList<>();
        List<Map<String, String>> map = iPropertyEquipDao.getBatchNumber(projectId, deviceType);

        if (map != null && !map.isEmpty()) {
            for (Map<String, String> m : map) {
                if(StringUtils.isNotEmpty(m.get("oldBatchNumber"))){
                    for(String oldBatchNumber :m.get("oldBatchNumber").split(",")){
                        listRemove.add(oldBatchNumber);
                    }
                }
                set.add(m.get("batchNumber"));
            }
        }
        if(!listRemove.isEmpty()){
            for(String old : listRemove){
                set.remove(old);
            }
        }

        return Arrays.asList(set.toArray(new String[0]));
    }

    /**
     * <desc>
     *      检测设备是否存在
     * </desc>
     *
     * @param deviceUnique
     * @param type
     * @return
     * @author Jiaqi.X
     * @createDate 2019/11/25
     */
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public Integer checkEquipExists(String deviceUnique,Integer type) {
        return iPropertyEquipDao.checkEquipExists(deviceUnique, type);
    }

    /**
     * <desc>
     *      访客二维码校验
     * </desc>
     *
     * @param checkQrCodeDTO
     * @return
     * @author Jiaqi.X
     * @createDate 2019/10/15
     */
    public Boolean checkVisitorQrcode(CheckQrCodeDTO checkQrCodeDTO) throws Exception {
        if(checkQrCodeDTO.getVersion() == 0) {
            checkQrCodeDTO.setUid(checkQrCodeDTO.getUid().length() > 8 ? checkQrCodeDTO.getUid().substring(
                    checkQrCodeDTO.getUid().length()-8,checkQrCodeDTO.getUid().length())
                    : checkQrCodeDTO.getUid());
            checkQrCodeDTO.setBatch(1);
            //校验标准家半径访客二维码
            Calendar beforeTime = Calendar.getInstance();
            beforeTime.setTime(DateUtil.formatStringToDate(checkQrCodeDTO.getBeginTime(),DateUtil.DATE_FORMAT_TYPE1));
            beforeTime.add(Calendar.MINUTE, +10);// 10分钟之后的时间
            Date beforeD = beforeTime.getTime();
            checkQrCodeDTO.setBeginTime(DateUtil.fomatDate(beforeD,DateUtil.DATE_FORMAT_TYPE1));
            AppVisitorPassCodeRecordPO po = iPropertyEquipDao.getVisitorQrcode(StringHandlerUtil.getProjectIdByDeviceUnique(checkQrCodeDTO.getDeviceUnique())
                    , checkQrCodeDTO.getUid(), checkQrCodeDTO.getBeginTime(), checkQrCodeDTO.getBatch(), checkQrCodeDTO.getMac());
            Map<String,Object> qrcodeConfigure = iPropertyEquipDao.getVisitorConfigure(StringHandlerUtil.getProjectIdByDeviceUnique(checkQrCodeDTO.getDeviceUnique()));
            String chargeMode = StringHandlerUtil.getNullOrStringForObject(qrcodeConfigure.get("chargeMode"));
            if (po != null && po.getNum() - po.getUseNum() > 0) {
                if((po.getSource()==2 || po.getSource()==5) && "2".equals(chargeMode)){
                    return true;
                }
                //查询房间可用次数
                PropertyQrcodeValidVO valid=iAppDeviceDao.getPropertyQrocdeVliadInfo(po.getRoomId());
                if(valid.getProjectChargeMode() == 2 && valid.getRoomChargeMode() == 1) {
                    Integer usableCount = iPropertyEquipDao.getRoomUsableCount(po.getRoomId());
                    if (usableCount != null && usableCount > 0) {
                        return true;
                    }else{
                        return false;
                    }
                }else if(valid.getProjectChargeMode() == 2 && valid.getRoomChargeMode() == 2){
                    Date endDate = DateUtil.formatStringToDate(valid.getEndTime(),DateUtil.YMDSQL);
                    Date now = DateUtil.formatStringToDate(DateUtil.fomatDate(new Date(),DateUtil.YMDSQL),DateUtil.YMDSQL);
                    if(now.getTime() > endDate.getTime()  ){
                        return false;
                    }else{
                        return true;
                    }
                }
                return true;
            }
        }else {
            if(checkQrCodeDTO.getBatch() == null || checkQrCodeDTO.getBatch () ==0){
                return true;
            }
            if (checkQrCodeDTO.getType() == 2) {
                //校验SDK访客二维码
                SdkQrcodeBatchRecord sdkQrcodeBatchRecord = iPropertyEquipDao.getSdkVisitorQrcodeBatchRecord(
                        StringHandlerUtil.getProjectIdByDeviceUnique(checkQrCodeDTO.getDeviceUnique()), checkQrCodeDTO.getUid(), checkQrCodeDTO.getBatch(),
                        checkQrCodeDTO.getBeginTime(), checkQrCodeDTO.getMac());
                if (sdkQrcodeBatchRecord == null) {
                    //新增访客记录
                    sdkQrcodeBatchRecord = new SdkQrcodeBatchRecord();
                    sdkQrcodeBatchRecord.setProjectId(StringHandlerUtil.getProjectIdBySn(checkQrCodeDTO.getSn()));
                    sdkQrcodeBatchRecord.setSdkQrcodeRecordId(LogicIdUtil.bussinessId());
                    sdkQrcodeBatchRecord.setUid(checkQrCodeDTO.getUid());
                    sdkQrcodeBatchRecord.setBatch(checkQrCodeDTO.getBatch());
                    sdkQrcodeBatchRecord.setBeginTime(DateUtil.formatStringToDate(checkQrCodeDTO.getBeginTime(), DateUtil.DATE_FORMAT_TYPE1));
                    sdkQrcodeBatchRecord.setMac(checkQrCodeDTO.getMac());
                    sdkQrcodeBatchRecord.setStatus(DataStatusEnum.NORMAL.getType());
                    sdkQrcodeBatchRecord.setCount(checkQrCodeDTO.getCount());
                    sdkQrcodeBatchRecord.setType(2);
                    sdkQrcodeBatchRecord.setPayCount(checkQrCodeDTO.getCount());
                    sdkQrcodeBatchRecord.setUsableCount(checkQrCodeDTO.getCount());
                    sdkQrcodeBatchRecord.setCreateTime(new Date());
                    iPropertyEquipDao.save(SqlUtil.durableData(sdkQrcodeBatchRecord, PlatformConstants.TABLE_SAVE));
                    return true;
                } else {
                    if (sdkQrcodeBatchRecord.getUsableCount() > 0) {
                        return true;
                    }
                }
            } else {
                //校验SDK业主二维码
                //业主
                SdkQrcodeBatchRecord sdkQrcodeBatchRecord = iPropertyEquipDao.getSdkOwnerQrcodeBatchRecord(
                        StringHandlerUtil.getProjectIdByDeviceUnique(checkQrCodeDTO.getDeviceUnique()), checkQrCodeDTO.getUid());
                if (sdkQrcodeBatchRecord == null) {
                    //新增业主
                    sdkQrcodeBatchRecord = new SdkQrcodeBatchRecord();
                    sdkQrcodeBatchRecord.setSdkQrcodeRecordId(LogicIdUtil.bussinessId());
                    sdkQrcodeBatchRecord.setUid(checkQrCodeDTO.getUid());
                    sdkQrcodeBatchRecord.setBatch(checkQrCodeDTO.getBatch());
                    sdkQrcodeBatchRecord.setMac(checkQrCodeDTO.getMac());
                    sdkQrcodeBatchRecord.setStatus(DataStatusEnum.NORMAL.getType());
                    sdkQrcodeBatchRecord.setCount(checkQrCodeDTO.getCount());
                    sdkQrcodeBatchRecord.setType(1);
                    sdkQrcodeBatchRecord.setPayCount(checkQrCodeDTO.getCount());
                    sdkQrcodeBatchRecord.setUsableCount(checkQrCodeDTO.getCount());
                    sdkQrcodeBatchRecord.setCreateTime(new Date());
                    sdkQrcodeBatchRecord.setProjectId(StringHandlerUtil.getProjectIdByDeviceUnique(checkQrCodeDTO.getDeviceUnique()));
                    iPropertyEquipDao.save(SqlUtil.durableData(sdkQrcodeBatchRecord, PlatformConstants.TABLE_SAVE));
                    return true;
                }else{
                    if(sdkQrcodeBatchRecord.getBatch() < checkQrCodeDTO.getBatch()){
                        SdkQrcodeBatchRecord newRecord = new SdkQrcodeBatchRecord();
                        newRecord.setSdkQrcodeRecordId(LogicIdUtil.bussinessId());
                        newRecord.setUid(checkQrCodeDTO.getUid());
                        newRecord.setBatch(checkQrCodeDTO.getBatch());
                        newRecord.setMac(checkQrCodeDTO.getMac());
                        newRecord.setCount(checkQrCodeDTO.getCount());
                        newRecord.setType(1);
                        newRecord.setPayCount(checkQrCodeDTO.getCount());
                        newRecord.setUsableCount(newRecord.getCount());
                        newRecord.setCreateTime(new Date());
                        newRecord.setStatus(DataStatusEnum.NORMAL.getType());
                        newRecord.setProjectId(StringHandlerUtil.getProjectIdBySn(StringHandlerUtil.getProjectIdByDeviceUnique(checkQrCodeDTO.getDeviceUnique())));
                        iPropertyEquipDao.save(SqlUtil.durableData(newRecord, PlatformConstants.TABLE_SAVE));
                        return true;
                    }
                    if (sdkQrcodeBatchRecord.getUsableCount() > 0) {
                        return true;
                    }
                }
            }
        }
        return false;
    }

    /**
     * <desc>
     *      上传二维码通行记录
     * </desc>
     *
     * @param jsonRecord
     * @author Jiaqi.X
     * @createDate 2019/10/24
     */
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public void uploadQrcodePssRecord(String jsonRecord,Integer deviceType,String sn) throws Exception {
        List<DeviceQrcodePassDTO> qrcodes =  JsonUtil.decode(jsonRecord, new TypeReference<List<DeviceQrcodePassDTO>>() {});
        String projectId = StringHandlerUtil.getProjectIdBySn(sn);
        String deviceName = "";
        String equipMode = "";
        String deviceUnique = "";
        if(deviceType == null){
            //云对讲
            deviceUnique = StringHandlerUtil.getDeviceUniqueBySn(sn);
            deviceName = iAppDeviceDao.getDeviceNameByDeviceUniqueAndType(deviceUnique,3);
            equipMode = iAppDeviceDao.getDeviceModeByDeviceUniqueAndType(deviceUnique,3);
            deviceType = 3;
        } else if (deviceType.equals(PropertyEquipTypeEnum.CLOUD_ELEVATOR_DEVICE_TYPE.getType())){
            //电梯
            deviceUnique = StringHandlerUtil.getElevatorDeviceUniqueBySn(sn);
            deviceName = iAppDeviceDao.getDeviceNameByDeviceUniqueAndType(deviceUnique,1);
            equipMode = iAppDeviceDao.getDeviceModeByDeviceUniqueAndType(deviceUnique,1);
            deviceType = 1;
        }else if(deviceType.equals(new Integer(17)) || deviceType.equals(PropertyEquipTypeEnum.CLOUD_WIPPEN_DEVICE_TYPE.getType())
                || deviceType.equals(PropertyEquipTypeEnum.CLOUD_UNIBODY_FACE_DEVICE.getType())|| deviceType.equals(PropertyEquipTypeEnum.HARDWARE_CLOUD_UNIBODY_ENTRANCE_DEVICE.getType())){
            //门禁 由于门禁或联动器存在一控制器多门情况，故需根据doorNum推断出sn
            if(qrcodes!=null){
                deviceUnique=StringHandlerUtil.getProjectIdBySn(sn) + "2" + StringHandlerUtil.formatStrLen(qrcodes.get(0).getDoorNum()==null?"0":qrcodes.get(0).getDoorNum().toString(),
                        "0",4,false,false);
            }
            deviceName = iAppDeviceDao.getDeviceNameByDeviceUniqueAndType(deviceUnique,2);
            equipMode = iAppDeviceDao.getDeviceModeByDeviceUniqueAndType(deviceUnique,2);
            deviceType = 2;
            if(deviceType == 17){
                deviceType = 17;
            }
        }
        //根据項目Id查询收费间隔时间 如同一个用户相同通行方式在收费间隔时间内只扣一次
        Integer feeIntervalTime = Integer.parseInt(iCloudElevatorDao.getFeeConfigTimeByProjectId(projectId));
        for(DeviceQrcodePassDTO dto : qrcodes) {
            if(StringUtils.isBlank(dto.getRoomNo())){
                dto.setRoomNo("0");
            }
            TimeTaskDevicePassRecordPO passRecordPO = new TimeTaskDevicePassRecordPO();
            if(dto.getUid().length() > 8){
                dto.setUid(dto.getUid().substring(dto.getUid().length()-8,dto.getUid().length()));
            }
            passRecordPO.setPdId(LogicIdUtil.bussinessId());
            passRecordPO.setProjectId(projectId);
            passRecordPO.setPassTime(DateUtil.formatStringToDate(dto.getOpenTime(), DateUtil.DATE_FORMAT_TYPE1));
            passRecordPO.setUploadTime(new Date());
            passRecordPO.setIsOpen(0);
            passRecordPO.setSynchro(0);
            passRecordPO.setStatus(DataStatusEnum.NORMAL.getType());
            passRecordPO.setCreateTime(new Date());
            passRecordPO.setDeviceUnique(deviceUnique);
            passRecordPO.setDeviceName(deviceName);
            passRecordPO.setDeviceType(deviceType);
            passRecordPO.setTimescount(dto.getPayment() == null ? 0: dto.getPayment());
            passRecordPO.setSystemType(1);
            //组装消费记录表信息
            ConsumeRecordInfoPO consumeRecordInfoPO = new ConsumeRecordInfoPO();
            consumeRecordInfoPO.setConsumeId(LogicIdUtil.bussinessId());
            consumeRecordInfoPO.setProjectId(projectId);
            consumeRecordInfoPO.setDeviceUnique(deviceUnique);
            consumeRecordInfoPO.setPassTime(DateUtil.formatStringToDate(dto.getOpenTime(), DateUtil.DATE_FORMAT_TYPE1));
            consumeRecordInfoPO.setStatus(DataStatusEnum.NORMAL.getType());
            consumeRecordInfoPO.setCreateTime(new Date());
            consumeRecordInfoPO.setUpdateTime(new Date());
            if(StringUtils.isNotBlank(dto.getImage())){
                //上传图片
                InputStream input = new ByteArrayInputStream(StringHandlerUtil.imageBase64StrToByte(dto.getImage()));
                passRecordPO.setFacePicUrl(this.uploadFile(input, "png"));
            }
            QrcodePassUserInfoVO vo = null;
            boolean pushBlackList = false;
            //是否扣次标识
            boolean mark = true;
            if(dto.getVersion() == 0) {
                //家半径二维码逻辑
                //查询用户
                //查询项目的预警次数
                Integer warningTimes = iCloudElevatorDao.getWarningTimesByProjectId(StringHandlerUtil.getProjectIdByDeviceUnique(deviceUnique));
                if (dto.getType() == 8 ) {
                    //业主
                    vo = iPropertyEquipDao.findOwnerQrcodeInfo(dto.getUid(), projectId, Integer.parseInt(dto.getRoomNo(), 16));
                    if(Integer.parseInt(dto.getRoomNo(), 16) != 0 && vo == null){
                        continue;
                    }
                    if(Integer.parseInt(dto.getRoomNo(), 16) == 0){
                        vo = iPropertyEquipDao.findOwnerQrcodeInfoByUidAndProjectId(dto.getUid(),projectId);
                        if(vo==null){
                            continue;
                        }
                    }
                    if(vo.getChargeMode() != null && vo.getChargeMode()==1){
                        mark = false;
                    }
                    passRecordPO.setUserId(vo.getUserId());
                    passRecordPO.setOpenType(8);
                    Map<String,Object> userMap =  iCloudElevatorDao.getUserType(projectId,vo.getUserId(),vo.getRoomId());
                    consumeRecordInfoPO.setRoomId(vo.getRoomId());
                    consumeRecordInfoPO.setUserId(vo.getUserId());
                    consumeRecordInfoPO.setPassType(1);
                    if(userMap!=null){
                        consumeRecordInfoPO.setHousesType((Integer) userMap.get("housesType"));
                        consumeRecordInfoPO.setUserInfo(userMap.get("phoneNum").toString());
                    }
                    consumeRecordInfoPO.setCreateUserId(vo.getUserId());
                    consumeRecordInfoPO.setOperateUserId(vo.getUserId());
                    //查询用户相同通行方式的最近一次记录
                    String lastTime = redisServicePassTime.get(String.format("%s%s%s%s",RedisConstant.REDIS_PASS_TIME_KEY_CACHE,projectId,vo.getUserId(),"8"));
                    //String lastTime = iCloudElevatorDao.getLastPassTimeByProjectId(projectId,vo.getUserId(),"8");
                    if(StringUtils.isNotEmpty(lastTime) && feeIntervalTime!=0){
                        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        Map<String,Object> map = DateUtil.reckonDate(dateFormat.format(DateUtil.formatStringToDate(dto.getOpenTime(), DateUtil.DATE_FORMAT_TYPE1)),lastTime);
                        Integer passTimeInterval = Integer.parseInt((map.get("s")).toString());
                        if(passTimeInterval <= feeIntervalTime){
                            mark = false;
                        }else{
                            redisServicePassTime.set(String.format("%s%s%s%s",RedisConstant.REDIS_PASS_TIME_KEY_CACHE,projectId,vo.getUserId(),"8"),RedisConstant.REDIS_PASS_TIME_KEY_CACHE_TIME,dto.getOpenTime());
                        }
                    }else{
                        redisServicePassTime.set(String.format("%s%s%s%s",RedisConstant.REDIS_PASS_TIME_KEY_CACHE,projectId,vo.getUserId(),"8"),RedisConstant.REDIS_PASS_TIME_KEY_CACHE_TIME,dto.getOpenTime());
                    }
                    //扣次
                    if (!dto.getRoomNo().equals("00") && dto.getPayment() == 1 && vo.getChargeMode() != null && vo.getChargeMode() == 2
                            && vo.getRoomChargeMode() != null && vo.getRoomChargeMode() == 1) {
                        if(mark){
                            passRecordPO.setLastPassCount(vo.getUsableCount()-1);
                            passRecordPO.setRoomDetail(vo.getRoomDetail());
                            consumeRecordInfoPO.setLastPassCount(vo.getUsableCount()-1);
                            if (StringUtils.isNotBlank(vo.getQrcodeBatchRecordId())) {
                                Integer row = iPropertyEquipDao.updateQrcodeRoomCount(vo.getQrcodeBatchRecordId(), vo.getUsableCount() > 1 ? 1 : 0);
                                if (row < 1 || vo.getUsableCount() <= 1 || (vo.getUsableCount()-1 == warningTimes)) {
                                    //推送黑名单数据
                                    pushBlackList = true;
                                }
                            }
                        }else{
                            passRecordPO.setLastPassCount(vo.getUsableCount());
                        }
                    }
                    if(iPropertyEquipDao.checkOwnerRecordExists(vo.getUserId(),projectId,dto.getOpenTime(),deviceUnique) > 0){
                        continue;
                    }
                } else if (dto.getType() == 11) {
                    //访客
                    Calendar beforeTime = Calendar.getInstance();
                    beforeTime.setTime(DateUtil.formatStringToDate(dto.getBeginTime(),DateUtil.DATE_FORMAT_TYPE1));
                    beforeTime.add(Calendar.MINUTE, +10);// 10分钟之后的时间
                    Date beforeD = beforeTime.getTime();
                    dto.setBeginTime(DateUtil.fomatDate(beforeD,DateUtil.DATE_FORMAT_TYPE1));
                    passRecordPO.setVisitorUuid(dto.getUid());
                    passRecordPO.setUserId(dto.getUid());
                    passRecordPO.setOpenType(11);
                    dto.setBatch(1);
                    vo = iPropertyEquipDao.findVisitorQrcodeInfo(dto.getUid(), projectId, dto.getBeginTime(), dto.getMac(), dto.getBatch());
                    if (vo != null) {
                        consumeRecordInfoPO.setRoomId(vo.getRoomId());
                        consumeRecordInfoPO.setUserId(vo.getUserId());
                        consumeRecordInfoPO.setHousesType(4);
                        consumeRecordInfoPO.setPassType(1);
                        consumeRecordInfoPO.setUserInfo(vo.getVisitorInfo());
                        consumeRecordInfoPO.setCreateUserId(vo.getUserId());
                        consumeRecordInfoPO.setOperateUserId(vo.getUserId());
                        passRecordPO.setPassId(vo.getUserId());
                        //查询用户相同通行方式的最近一次记录
                        String lastTime = redisServicePassTime.get(String.format("%s%s%s%s",RedisConstant.REDIS_PASS_TIME_KEY_CACHE,projectId,vo.getUserId(),"11"));
                        //String lastTime = iCloudElevatorDao.getLastPassTimeByProjectId(projectId,dto.getUid(),"11");
                        if(StringUtils.isNotEmpty(lastTime) && feeIntervalTime!=0){
                            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                            Map<String,Object> map = DateUtil.reckonDate(dateFormat.format(DateUtil.formatStringToDate(dto.getOpenTime(), DateUtil.DATE_FORMAT_TYPE1)),lastTime);
                            Integer passTimeInterval = Integer.parseInt((map.get("s")).toString());
                            if(passTimeInterval <= feeIntervalTime){
                                mark = false;
                            }else{
                                redisServicePassTime.set(String.format("%s%s%s%s",RedisConstant.REDIS_PASS_TIME_KEY_CACHE,projectId,vo.getUserId(),"11"),RedisConstant.REDIS_PASS_TIME_KEY_CACHE_TIME,dto.getOpenTime());
                            }
                        }else{
                            redisServicePassTime.set(String.format("%s%s%s%s",RedisConstant.REDIS_PASS_TIME_KEY_CACHE,projectId,vo.getUserId(),"11"),RedisConstant.REDIS_PASS_TIME_KEY_CACHE_TIME,dto.getOpenTime());
                        }
                        if(vo.getChargeMode()==1){
                            mark = false;
                        }
                        if(vo.getVisitorQrCodeTimesRestrict()==1 && equipMode.equals("2")){
                            //更新访客使用次数
                            iPropertyEquipDao.udpateAppVisitorUseNum(vo.getUserId());
                        }
                        //扣房间剩余通行次数
                        if (dto.getPayment() == 1) {
                            if(mark){
                                passRecordPO.setLastPassCount(vo.getNum()-vo.getUseNum()-1);
                                passRecordPO.setRoomDetail(vo.getRoomDetail());
                                consumeRecordInfoPO.setLastPassCount(vo.getNum()-vo.getUseNum()-1);
                                //更新业主房间次数
                                if(vo.getChargeMode() != null && vo.getChargeMode() == 2
                                        && vo.getRoomChargeMode() != null && vo.getRoomChargeMode() == 1 && vo.getSource()!=2 && vo.getSource()!=5) {
                                    if (StringUtils.isNotBlank(vo.getQrcodeBatchRecordId())) {
                                        Integer row = iPropertyEquipDao.updateQrcodeRoomCount(vo.getQrcodeBatchRecordId(), vo.getUsableCount() > 1 ? 1 : 0);
                                        if (row < 1 || vo.getUsableCount() == 1 || (vo.getUsableCount()-1 == warningTimes)) {
                                            //推送黑名单数据
                                            pushBlackList = true;
                                        }
                                    }
                                }
                                if(vo.getSource()==2 || vo.getSource()==5){
                                    mark = false;
                                }
                            }else{
                                passRecordPO.setLastPassCount(vo.getNum()-vo.getUseNum());
                            }
                        }
                        if(iPropertyEquipDao.checkVisitorExists(vo.getUserId(),dto.getOpenTime(),deviceUnique) > 0){
                            continue;
                        }
                    }else{
                        continue;
                    }
                }else if(dto.getType() == 17){
                    //管理员
                    vo = iPropertyEquipDao.findManageQrcodeInfo(dto.getUid(), projectId);
                    if(vo == null){
                        vo = iPropertyEquipDao.findManageQrcodeInfoByPropertyApp(dto.getUid(), projectId);
                    }
                    if(vo == null ){
                        continue;
                    }
                    passRecordPO.setUserId(vo.getUserId());
                    passRecordPO.setOpenType(17);
                }
                passRecordPO.setQrcodeSource(1);
            }else{
                //sdk二维码上传通行记录逻辑
                if(dto.getType() == 8 || dto.getType() == 17) {
                    //业主
                    if(dto.getCount() > 0 && dto.getPayment() != null && dto.getPayment() ==1) {
                        SdkQrcodeBatchRecord sdkQrcodeBatchRecord = iPropertyEquipDao.getSdkOwnerQrcodeBatchRecord(projectId, dto.getUid());
                        if (sdkQrcodeBatchRecord != null && sdkQrcodeBatchRecord.getBatch() <= dto.getBatch() && sdkQrcodeBatchRecord.getUsableCount() != null) {
                            iPropertyEquipDao.updateSDKQrcodeCount(1, sdkQrcodeBatchRecord.getSdkQrcodeRecordId(), sdkQrcodeBatchRecord.getUsableCount() > 1 ? 1 : 0);
                        }
                    }
                    passRecordPO.setOpenType(8);
                    //检测sdk记录是否已存在
                    if(iPropertyEquipDao.checkSDKQrcodeRecordExists(dto.getUid(),projectId,dto.getOpenTime(),deviceUnique,8) > 0){
                        continue;
                    }
                }else {
                    if(dto.getCount() > 0  && dto.getPayment() != null && dto.getPayment() ==1) {
                        //访客
                        SdkQrcodeBatchRecord sdkQrcodeBatchRecord = iPropertyEquipDao.getSdkVisitorQrcodeBatchRecord(
                                projectId, dto.getUid(), dto.getBatch(), dto.getBeginTime(), dto.getMac());
                        if(sdkQrcodeBatchRecord != null && sdkQrcodeBatchRecord.getUsableCount()!=null) {
                            iPropertyEquipDao.updateSDKQrcodeCount(2, sdkQrcodeBatchRecord.getSdkQrcodeRecordId(), sdkQrcodeBatchRecord.getUsableCount() > 1 ? 1 : 0);
                        }
                    }
                    passRecordPO.setOpenType(11);
                    if(iPropertyEquipDao.checkSDKQrcodeRecordExists(dto.getUid(),projectId,dto.getOpenTime(),deviceUnique,11) > 0){
                        continue;
                    }
                }
                passRecordPO.setUserId(dto.getUid());
                passRecordPO.setOnline(dto.getOnline());
                passRecordPO.setQrcodeSource(2);
            }
            if(pushBlackList && vo!=null){
                //推送数据
                //推送黑名单更新数据
                List<DeviceBusinessChangeLogPO> changes = new ArrayList<>();
                List<DeviceBusinessElevatorChangeLogPO> elevatorChanges = new ArrayList<>();
                List<DeviceBusinessEntranceChangeLogPO> entranceChanges = new ArrayList<>();
                Map<String,Object> blackList = new HashMap<>();
                blackList.put("projectId", projectId);
                blackList.put("roomId", vo.getRoomId());
                blackList.put("version",dto.getVersion());
                DeviceBusinessChangeLogPO po = new DeviceBusinessChangeLogPO(SmartCommunityEnum.PUSH_BLACK_LIST, JsonUtil.toJSON(blackList), projectId);
                changes.add(po);
                DeviceBusinessElevatorChangeLogPO elevatorPo = new DeviceBusinessElevatorChangeLogPO(projectId, CloudElevatorChangeBusinessEnum.PUSH_BLACK_LIST, JsonUtil.toJSON(blackList));
                elevatorChanges.add(elevatorPo);
                DeviceBusinessEntranceChangeLogPO entrancePO = new DeviceBusinessEntranceChangeLogPO(projectId, CloudEntranceChangeBusinessEnum.PUSH_BLACK_LIST, JsonUtil.toJSON(blackList));
                entranceChanges.add(entrancePO);
                JSONObject pushJs = new JSONObject();
                pushJs.put("data", changes);
                //发送云对讲业务指令
                messageSender.send(RabbitMQConstant.RABBITMQ_HANDLE_SMART_COMMUNITY_ORDERS_QUEUE, JsonUtil.toJSON(pushJs), RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_EXCHANGE, RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_ROUTING_KEY);
                pushJs.put("data", elevatorChanges);
                //推送云电梯业务指令
                messageSender.send(
                        RabbitMQConstant.RABBITMQ_HANDLE_CLOUD_ELEVATOR_CHANGE_BUSINESS_QUEUE,
                        JsonUtil.toJSON(pushJs),
                        RabbitMQConstant.RABBITMQ_CLOUD_ELEVATOR_CHANGE_BUSINESS_EXCHANGE,
                        RabbitMQConstant.RABBITMQ_CLOUD_ELEVATOR_CHANGE_BUSINESS_ROUTING_KEY);
                //发送云门禁业务指令
                pushJs.put("data", entranceChanges);
                messageSender.send(
                        RabbitMQConstant.RABBITMQ_HANDLE_CLOUD_ENTRANCE_CHANGE_BUSINESS_QUEUE,
                        JSON.toJSONString(pushJs),
                        RabbitMQConstant.RABBITMQ_CLOUD_ENTRANCE_CHANGE_BUSINESS_EXCHANGE,
                        RabbitMQConstant.RABBITMQ_CLOUD_ENTRANCE_CHANGE_BUSINESS_ROUTING_KEY
                );
            }
            //保存通行记录
            iAppDevicePassRecordDao.save(SqlUtil.durableData(passRecordPO,PlatformConstants.TABLE_SAVE));
            //如果扣次则保存消费记录
            if(mark && dto.getVersion() == 0  && ( dto.getPayment() != null && dto.getPayment() ==1) && dto.getType() != 17 && StringUtils.isNotEmpty(consumeRecordInfoPO.getRoomId())){
                iAppDevicePassRecordDao.save(SqlUtil.durableData(consumeRecordInfoPO,PlatformConstants.TABLE_SAVE));
            }
        }
    }

    /**
     * <desc>
     *      获取批次号下的不同设备类型的设备数量。
     * <desc/>
     *
     * @param  projectId 项目ID
     * @param  deviceType 设备类型1-电梯 2-门禁 3-云对讲 4平板
     * @param  batchNumber 批次号
     * @return
     * @author Juguang.S
     * @createDate 2019-11-22
     */
    @Override
    public Integer getDeviceCountByBatchNumber(String projectId, String deviceType, String batchNumber) throws Exception {
        Integer count = 0;
        if(StringUtils.isNotEmpty(batchNumber)){
            count = iPropertyEquipDao.getDeviceCountByBatchNumber(projectId, deviceType,batchNumber);
        }else{
            count = iPropertyEquipDao.getDeviceCountByAllBatchNumber(projectId, deviceType);
            List<String> list = iPropertyEquipDao.getOldBatchNumber(projectId, deviceType);
            Set<String> set = new HashSet<>();
            if(list!=null){
                for(String oldBatchNumber : list){
                    for(String str : oldBatchNumber.split(",")){
                        set.add(str);
                    }
                }
            }
            if(set.size()>0){
                Integer oldCount = iPropertyEquipDao.getOldBatchNumberCount(projectId, deviceType,set);
                if(oldCount!=null){
                    count = count-oldCount;
                }
            }
        }

        return count;
    }

    /**
     * <desc>
     *      Ftp上传文件，返回Url.
     * </desc>
     *
     * @param inputStream 文件流
     * @param fileType 文件类型
     * @return 文件上传成功后会返回Url,否则返回空
     * @author Qiang.S
     * @createDate 2019/02/22
     */
    private String uploadFile(InputStream inputStream, String fileType) throws IOException {
        String fileUrl = "";
        UploadFileUtil.UploadFile uploadFileUtil = new UploadFileUtil().new UploadFile(
                FILE_FTP_HOST,
                FILE_FTP_USERNAME,
                FILE_FTP_PASSWORD,
                FILE_FTP_PORT,
                inputStream,
                fileType,
                FILE_ACCESS_URL,
                FileCatalogEnum.FACE_PASS_FILE.getType()
        );
        Map<String, Object> resultMap = UploadFileUtil.uploadFile(uploadFileUtil);
        Boolean returnCode = (Boolean)resultMap.get("returnCode");
        if (returnCode == false){
            return fileUrl;
        }
        fileUrl = resultMap.get("accessPath").toString();
        return fileUrl;
    }

    /**
     * <desc>
     *      检测业主记录是否已存在
     * </desc>
     *
     * @param userId
     * @param projectId
     * @param passTime
     * @return
     * @author Jiaqi.X
     * @createDate 2019/11/18
     */
    public Integer checkOwnerRecordExists(String userId,String projectId,String passTime,String deviceUnique){
        return iPropertyEquipDao.checkOwnerRecordExists(userId,projectId,passTime,deviceUnique);
    }

    /**
     * <desc>
     *      检测访客通行记录是否已存在
     * </desc>
     *
     * @param passId
     * @return
     * @author Jiaqi.X
     * @createDate 2019/11/18
     */
    public Integer checkVisitorExists(String passId,String passTime,String deviceUnique){
        return iPropertyEquipDao.checkVisitorExists(passId,passTime,deviceUnique);
    }

    /**
     * <desc>
     *      检测sdk通行记录是否存在
     * </desc>
     *
     * @param uid
     * @param projectId
     * @param openTime
     * @return
     * @author Jaiqi.X
     * @createDate 2019/11/18
     */
    public Integer checkSDKQrcodeRecordExists(String uid,String projectId,String openTime,String deviceUnique,Integer passType) {
        return iPropertyEquipDao.checkSDKQrcodeRecordExists(uid, projectId, openTime, deviceUnique, passType);
    }

    /**
     * <desc>
     *      获取设备信息 人脸api
     * </desc>
     *
     * @param dto
     * @author Qiang.S
     * @createDate 2019/11/06
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public List<SDKFaceDeviceInfoGetVO> getEquipInfoForApi(CloudFaceApiDTO dto) {
        if (dto.getDeviceType() == 1) {//云对讲
            return iPropertyEquipDao.getIntercomInfoForApi(dto.getProjectId());
        }else if (dto.getDeviceType() == 2) {//平板
            return iPropertyEquipDao.getPadInfoForApi(dto.getProjectId());
        }else if (dto.getDeviceType() == 3) {//电梯
            return iPropertyEquipDao.getElevatorInfoForApi(dto.getProjectId());
        }else if (dto.getDeviceType() == 4) {//门禁
            return iPropertyEquipDao.getEntranceInfoForApi(dto.getProjectId());
        }
        return null;
    }

    /**
     * <desc>
     *      分页查询设备相关人员权限
     * </desc>
     * @param deviceUnique 设备唯一码
     * @param deviceType 1-电梯 2-门禁 3-云对讲
     * @param userType 1-业主 2-访客 3-临时
     * @return
     * @author Qiang.S
     * @createDate 2020/06/02
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public Page<PropertyEquipUserInfoVO> getEquipUserInfo(String deviceUnique, String deviceType, String userType, Integer currentPage, Integer pageSize) {
        Page<PropertyEquipUserInfoVO> page = new Page<>();
        page.getPage().setCurrentPage(currentPage.toString());
        page.getPage().setPageSize(pageSize.toString());
        List<Integer> list = new ArrayList<>();
        if ("1".equals(userType)) {//业主权限
            if ("1".equals(deviceType)) {//电梯
                list.add(2);
                list.add(4);
                page.setRows(iPropertyEquipDao.getElevatorUserInfo(deviceUnique,list,page.getPage().getStartSlip(), page.getPage().getPageSize()),
                        iPropertyEquipDao.getElevatorUserInfoCount(deviceUnique,list));
                return page;
            }else if ("2".equals(deviceType)) {//门禁
                list.add(2);
                list.add(4);
                page.setRows(iPropertyEquipDao.getEntranceUserInfo(deviceUnique,list,page.getPage().getStartSlip(), page.getPage().getPageSize()),
                        iPropertyEquipDao.getEntranceUserInfoCount(deviceUnique,list));
                return page;
            }else if ("3".equals(deviceType)) {//云对讲
                list.add(2);
                list.add(4);
                page.setRows(iPropertyEquipDao.getCloudTalkUserInfo(deviceUnique,list,page.getPage().getStartSlip(), page.getPage().getPageSize()),
                        iPropertyEquipDao.getCloudTalkUserInfoCount(deviceUnique,list));
                return page;
            }
        }else if ("2".equals(userType)) {//访客权限
            if ("1".equals(deviceType)) {//电梯
                page.setRows(iPropertyEquipDao.getElevatorVisitorUserInfo(deviceUnique,page.getPage().getStartSlip(), page.getPage().getPageSize()),
                        iPropertyEquipDao.getElevatorVisitorUserInfoCount(deviceUnique));
                return page;
            }else if ("2".equals(deviceType)) {//门禁
                DeviceEntranceInfoPO po = iPropertyEquipDao.getEntranceByDeviceUnique(deviceUnique);
                page.setRows(iPropertyEquipDao.getEntranceVisitorUserInfo(deviceUnique,po.getEntranceType(),page.getPage().getStartSlip(), page.getPage().getPageSize()),
                        iPropertyEquipDao.getEntranceVisitorUserInfoCount(deviceUnique,po.getEntranceType()));
                return page;
            }else if ("3".equals(deviceType)) {//云对讲
                int smartType = iCloudTalkSDKMediaDao.getCloudIntercomByProjectIdAndDeviceUnique(StringHandlerUtil.getProjectIdByDeviceUnique(deviceUnique),deviceUnique);
                page.setRows(iPropertyEquipDao.getCloudTalkVisitorUserInfo(deviceUnique,smartType,page.getPage().getStartSlip(), page.getPage().getPageSize()),
                        iPropertyEquipDao.getCloudTalkVisitorUserInfoCount(deviceUnique,smartType));
                return page;
            }
        }else if ("3".equals(userType)) {//临时权限
            if ("1".equals(deviceType)) {//电梯
                list.add(1);
                list.add(5);
                page.setRows(iPropertyEquipDao.getElevatorUserInfo(deviceUnique,list,page.getPage().getStartSlip(), page.getPage().getPageSize()),
                        iPropertyEquipDao.getElevatorUserInfoCount(deviceUnique,list));
                return page;
            }else if ("2".equals(deviceType)) {//门禁
                list.add(1);
                list.add(5);
                list.add(6);
                page.setRows(iPropertyEquipDao.getEntranceUserInfo(deviceUnique,list,page.getPage().getStartSlip(), page.getPage().getPageSize()),
                        iPropertyEquipDao.getEntranceUserInfoCount(deviceUnique,list));
                return page;
            }else if ("3".equals(deviceType)) {//云对讲
                list.add(1);
                list.add(5);
                page.setRows(iPropertyEquipDao.getCloudTalkUserInfo(deviceUnique,list,page.getPage().getStartSlip(), page.getPage().getPageSize()),
                        iPropertyEquipDao.getCloudTalkUserInfoCount(deviceUnique,list));
                return page;
            }
        }
        return null;
    }


    /**
     * <desc>
     *      通过地址获取电梯设备
     * </desc>
     *
     * @param address
     * @return
     * @author Jiaqi.X
     * @createDate 2019/10/15
     */
    @Override
    public List<CloudElevatorVO> getElevatorListByAddress(Map<String,Object> address){
        return iPropertyEquipDao.getElevatorListByAddress(address);
    }

    /**
     * <desc>
     *      组装授权列表查询参数
     * </desc>
     *
     * @param  propertyEquipAuthGetDTO
     * @return 查询参数map
     * @Author Zhu.yj
     * @createDate  2021/4/14
     */
    private Map<String, Object> assembleSearchMap(PropertyEquipAuthGetDTO propertyEquipAuthGetDTO, Page<PropertyEquipSimpleVO> page) throws Exception{
        Map<String, Object> params = SqlUtil.convertBeanToMapParams(propertyEquipAuthGetDTO);
        page.getPage().setPageSize(propertyEquipAuthGetDTO.getPageSize());
        page.getPage().setCurrentPage(propertyEquipAuthGetDTO.getCurrentPage());
        params.put("currentPage", page.getPage().getStartSlip());
        params.put("pageSize", page.getPage().getPageSize());
        params.put("projectId", propertyEquipAuthGetDTO.getProjectId());
        String buildId = propertyEquipAuthGetDTO.getBuildId();
        if (StringUtils.isNotEmpty(buildId)) {
            params.put("buildIdIn", buildId);
        }
        String unitId = propertyEquipAuthGetDTO.getUnitId();
        if (StringUtils.isNotEmpty(unitId)) {
            params.put("unitIdIn", unitId);
        }
        return params;
    }

    /**
     * <desc>
     *      组装返回门禁列表
     * </desc>
     *
     * @param deviceList 查询出的设备列表
     * @return
     * @Author Zhu.yj
     * @createDate  2021/4/15
     */
    private List<PropertyEquipSimpleVO> assembDeviceVO(List<PropertyEquipGetVO> deviceList){
        List<PropertyEquipSimpleVO> resultList = new ArrayList<>();
        if (null != deviceList && deviceList.size() > 0) {
            for (PropertyEquipGetVO propertyEquipGetVO : deviceList) {
                String deviceUnique = propertyEquipGetVO.getDeviceUnique();
                PropertyEquipSimpleVO equipSimpleVO = new PropertyEquipSimpleVO(deviceUnique,
                        propertyEquipGetVO.getDeviceName(), this.getEquipAddress(deviceUnique, propertyEquipGetVO.getEntranceType()));
                equipSimpleVO.setDeviceId(propertyEquipGetVO.getDeviceId());
                equipSimpleVO.setRoleName(propertyEquipGetVO.getRoleName());
                equipSimpleVO.setDeviceAddress(this.getEquipAddressStr(deviceUnique, propertyEquipGetVO.getEntranceType()));
                resultList.add(equipSimpleVO);
            }
        }
        return resultList;
    }

    /**
     * <desc>
     *      根据从数据库中取出的groupId,elevatorAuth(1,00000000000000000000100111111),转换为(deviceUnique,groupId)
     * </desc>
     *
     * @param projectId 项目id
     * @return
     * @Author Zhu.yj
     * @createDate  2021/4/1
     */
    private Map<String, String> getElevatorGroup(String projectId){
        Map<String, String> deviceGroups = new HashMap<>();
        Map<String, String> returnDeviceGroup = new HashMap<>();
        //找出所有角色组下的电梯，再转换成电梯拥有的角色组
        List<Map<String, String>> groupDevices = iPropertyEquipDao.getGroupDevice(projectId);
        for (int i = 0; i< groupDevices.size(); i++){
            deviceGroups.put(groupDevices.get(i).get("groupName"), groupDevices.get(i).get("deviceAuth"));
        }

        for (Map.Entry entry : deviceGroups.entrySet()){
            List<String> deviceIdList = StringHandlerUtil.splitStringList(StringHandlerUtil.convertAuth(entry.getValue().toString(), "1"));
            for (String deviceId : deviceIdList){
                String deviceUnqiue = projectId + PropertyEquipTypeEnum.ELEVATOR.getType() + deviceId;
                if (returnDeviceGroup.get(deviceUnqiue) != null){
                    returnDeviceGroup.put(deviceUnqiue, returnDeviceGroup.get(deviceUnqiue) +"," + entry.getKey());
                }else {
                    returnDeviceGroup.put(deviceUnqiue, entry.getKey().toString());
                }
            }
        }
        return returnDeviceGroup;
    }
}
